001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2016, Connect2id Ltd. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.jose.jwk; 019 020 021import java.io.Serializable; 022import java.math.BigInteger; 023import java.net.URI; 024import java.security.*; 025import java.security.cert.CertificateEncodingException; 026import java.security.cert.X509Certificate; 027import java.security.interfaces.RSAMultiPrimePrivateCrtKey; 028import java.security.interfaces.RSAPrivateCrtKey; 029import java.security.interfaces.RSAPrivateKey; 030import java.security.interfaces.RSAPublicKey; 031import java.security.spec.*; 032import java.text.ParseException; 033import java.util.*; 034 035import com.nimbusds.jose.Algorithm; 036import com.nimbusds.jose.JOSEException; 037import com.nimbusds.jose.util.Base64; 038import com.nimbusds.jose.util.Base64URL; 039import com.nimbusds.jose.util.ByteUtils; 040import com.nimbusds.jose.util.JSONObjectUtils; 041import net.jcip.annotations.Immutable; 042import net.minidev.json.JSONArray; 043import net.minidev.json.JSONObject; 044 045 046/** 047 * Public and private {@link KeyType#RSA RSA} JSON Web Key (JWK). This class is 048 * immutable. 049 * 050 * <p>Provides RSA JWK import from / export to the following standard Java 051 * interfaces and classes: 052 * 053 * <ul> 054 * <li>{@link java.security.interfaces.RSAPublicKey} 055 * <li>{@link java.security.interfaces.RSAPrivateKey} 056 * <ul> 057 * <li>{@link java.security.interfaces.RSAPrivateCrtKey} 058 * <li>{@link java.security.interfaces.RSAMultiPrimePrivateCrtKey} 059 * </ul> 060 * <li>{@link java.security.PrivateKey} for an RSA key in a PKCS#11 store 061 * <li>{@link java.security.KeyPair} 062 * </ul> 063 * 064 * <p>Example JSON object representation of a public RSA JWK: 065 * 066 * <pre> 067 * { 068 * "kty" : "RSA", 069 * "n" : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 070 * 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs 071 * tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 072 * QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI 073 * SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb 074 * w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", 075 * "e" : "AQAB", 076 * "alg" : "RS256", 077 * "kid" : "2011-04-29" 078 * } 079 * </pre> 080 * 081 * <p>Example JSON object representation of a public and private RSA JWK (with 082 * both the first and the second private key representations): 083 * 084 * <pre> 085 * { 086 * "kty" : "RSA", 087 * "n" : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 088 * 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs 089 * tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 090 * QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI 091 * SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb 092 * w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", 093 * "e" : "AQAB", 094 * "d" : "X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9 095 * M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqij 096 * wp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d 097 * _cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBz 098 * nbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFz 099 * me1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q", 100 * "p" : "83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPV 101 * nwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqV 102 * WlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs", 103 * "q" : "3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyum 104 * qjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgx 105 * kIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk", 106 * "dp" : "G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oim 107 * YwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_Nmtu 108 * YZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0", 109 * "dq" : "s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUU 110 * vMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9 111 * GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk", 112 * "qi" : "GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzg 113 * UIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rx 114 * yR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU", 115 * "alg" : "RS256", 116 * "kid" : "2011-04-29" 117 * } 118 * </pre> 119 * 120 * <p>Use the builder to create a new RSA JWK: 121 * 122 * <pre> 123 * RSAKey key = new RSAKey.Builder(n, e) 124 * .keyUse(KeyUse.SIGNATURE) 125 * .keyID("123") 126 * .build(); 127 * </pre> 128 * 129 * <p>See RFC 3447. 130 * 131 * <p>See http://en.wikipedia.org/wiki/RSA_%28algorithm%29 132 * 133 * @author Vladimir Dzhuvinov 134 * @author Justin Richer 135 * @author Cedric Staub 136 * @version 2017-01-10 137 */ 138@Immutable 139public final class RSAKey extends JWK implements AssymetricJWK { 140 141 142 private static final long serialVersionUID = 1L; 143 144 145 /** 146 * Other Primes Info, represents the private {@code oth} parameter of a 147 * RSA JWK. This class is immutable. 148 */ 149 @Immutable 150 public static class OtherPrimesInfo implements Serializable { 151 152 153 private static final long serialVersionUID = 1L; 154 155 156 /** 157 * The prime factor. 158 */ 159 private final Base64URL r; 160 161 162 /** 163 * The factor Chinese Remainder Theorem (CRT) exponent. 164 */ 165 private final Base64URL d; 166 167 168 /** 169 * The factor Chinese Remainder Theorem (CRT) coefficient. 170 */ 171 private final Base64URL t; 172 173 174 /** 175 * Creates a new JWK Other Primes Info with the specified 176 * parameters. 177 * 178 * @param r The prime factor. Must not be {@code null}. 179 * @param d The factor Chinese Remainder Theorem (CRT) 180 * exponent. Must not be {@code null}. 181 * @param t The factor Chinese Remainder Theorem (CRT) 182 * coefficient. Must not be {@code null}. 183 */ 184 public OtherPrimesInfo(final Base64URL r, final Base64URL d, final Base64URL t) { 185 186 if (r == null) { 187 188 throw new IllegalArgumentException("The prime factor must not be null"); 189 } 190 191 this.r = r; 192 193 if (d == null) { 194 195 throw new IllegalArgumentException("The factor CRT exponent must not be null"); 196 } 197 198 this.d = d; 199 200 if (t == null) { 201 202 throw new IllegalArgumentException("The factor CRT coefficient must not be null"); 203 } 204 205 this.t = t; 206 } 207 208 209 /** 210 * Creates a new JWK Other Primes Info from the specified 211 * {@code java.security.spec.RSAOtherPrimeInfo} instance. 212 * 213 * @param oth The RSA Other Primes Info instance. Must not be 214 * {@code null}. 215 */ 216 public OtherPrimesInfo(final RSAOtherPrimeInfo oth) { 217 218 r = Base64URL.encode(oth.getPrime()); 219 d = Base64URL.encode(oth.getExponent()); 220 t = Base64URL.encode(oth.getCrtCoefficient()); 221 } 222 223 224 /** 225 * Gets the prime factor ({@code r}). 226 * 227 * @return The prime factor. 228 */ 229 public Base64URL getPrimeFactor() { 230 231 return r; 232 } 233 234 235 /** 236 * Gets factor Chinese Remainder Theorem (CRT) exponent 237 * ({@code d}). 238 * 239 * @return The factor Chinese Remainder Theorem (CRT) exponent. 240 */ 241 public Base64URL getFactorCRTExponent() { 242 243 return d; 244 } 245 246 247 /** 248 * The factor Chinese Remainder Theorem (CRT) coefficient 249 * ({@code t}). 250 * 251 * @return The factor Chinese Remainder Theorem (CRT) 252 * coefficient. 253 */ 254 public Base64URL getFactorCRTCoefficient() { 255 256 return t; 257 } 258 259 260 /** 261 * Converts the specified array of 262 * {@code java.security.spec.RSAOtherPrimeInfo} instances to a 263 * list of JWK Other Prime Infos. 264 * 265 * @param othArray Array of RSA Other Primes Info instances. 266 * May be be {@code null}. 267 * 268 * @return The corresponding list of JWK Other Prime Infos, or 269 * empty list of the array was {@code null}. 270 */ 271 public static List<OtherPrimesInfo> toList(final RSAOtherPrimeInfo[] othArray) { 272 273 List<OtherPrimesInfo> list = new ArrayList<>(); 274 275 if (othArray == null) { 276 277 // Return empty list 278 return list; 279 } 280 281 for (RSAOtherPrimeInfo oth: othArray) { 282 283 list.add(new OtherPrimesInfo(oth)); 284 } 285 286 return list; 287 } 288 } 289 290 291 /** 292 * Builder for constructing RSA JWKs. 293 * 294 * <p>Example usage: 295 * 296 * <pre> 297 * RSAKey key = new RSAKey.Builder(n, e). 298 * privateExponent(d). 299 * algorithm(JWSAlgorithm.RS512). 300 * keyID("456"). 301 * build(); 302 * </pre> 303 */ 304 public static class Builder { 305 306 307 // Public RSA params 308 309 /** 310 * The modulus value for the RSA key. 311 */ 312 private final Base64URL n; 313 314 315 /** 316 * The public exponent of the RSA key. 317 */ 318 private final Base64URL e; 319 320 321 // Private RSA params, 1st representation 322 323 /** 324 * The private exponent of the RSA key. 325 */ 326 private Base64URL d; 327 328 329 // Private RSA params, 2nd representation 330 331 /** 332 * The first prime factor of the private RSA key. 333 */ 334 private Base64URL p; 335 336 337 /** 338 * The second prime factor of the private RSA key. 339 */ 340 private Base64URL q; 341 342 343 /** 344 * The first factor Chinese Remainder Theorem exponent of the 345 * private RSA key. 346 */ 347 private Base64URL dp; 348 349 350 /** 351 * The second factor Chinese Remainder Theorem exponent of the 352 * private RSA key. 353 */ 354 private Base64URL dq; 355 356 357 /** 358 * The first Chinese Remainder Theorem coefficient of the private RSA 359 * key. 360 */ 361 private Base64URL qi; 362 363 364 /** 365 * The other primes information of the private RSA key, should 366 * they exist. When only two primes have been used (the normal 367 * case), this parameter MUST be omitted. When three or more 368 * primes have been used, the number of array elements MUST be 369 * the number of primes used minus two. 370 */ 371 private List<OtherPrimesInfo> oth; 372 373 374 // Private RSA key, as PKCS#11 handle 375 376 /** 377 * The private RSA key, as PKCS#11 handle. 378 */ 379 private PrivateKey priv; 380 381 382 /** 383 * The key use, optional. 384 */ 385 private KeyUse use; 386 387 388 /** 389 * The key operations, optional. 390 */ 391 private Set<KeyOperation> ops; 392 393 394 /** 395 * The intended JOSE algorithm for the key, optional. 396 */ 397 private Algorithm alg; 398 399 400 /** 401 * The key ID, optional. 402 */ 403 private String kid; 404 405 406 /** 407 * X.509 certificate URL, optional. 408 */ 409 private URI x5u; 410 411 412 /** 413 * X.509 certificate thumbprint, optional. 414 */ 415 private Base64URL x5t; 416 417 418 /** 419 * The X.509 certificate chain, optional. 420 */ 421 private List<Base64> x5c; 422 423 424 /** 425 * Reference to the underlying key store, {@code null} if none. 426 */ 427 private KeyStore ks; 428 429 430 /** 431 * Creates a new RSA JWK builder. 432 * 433 * @param n The the modulus value for the public RSA key. It is 434 * represented as the Base64URL encoding of value's 435 * big endian representation. Must not be 436 * {@code null}. 437 * @param e The exponent value for the public RSA key. It is 438 * represented as the Base64URL encoding of value's 439 * big endian representation. Must not be 440 * {@code null}. 441 */ 442 public Builder(final Base64URL n, final Base64URL e) { 443 444 // Ensure the public params are defined 445 446 if (n == null) { 447 throw new IllegalArgumentException("The modulus value must not be null"); 448 } 449 450 this.n = n; 451 452 453 if (e == null) { 454 throw new IllegalArgumentException("The public exponent value must not be null"); 455 } 456 457 this.e = e; 458 } 459 460 461 /** 462 * Creates a new RSA JWK builder. 463 * 464 * @param pub The public RSA key to represent. Must not be 465 * {@code null}. 466 */ 467 public Builder(final RSAPublicKey pub) { 468 469 n = Base64URL.encode(pub.getModulus()); 470 e = Base64URL.encode(pub.getPublicExponent()); 471 } 472 473 474 /** 475 * Creates a new RSA JWK builder. 476 * 477 * @param rsaJWK The RSA JWK to start with. Must not be 478 * {@code null}. 479 */ 480 public Builder(final RSAKey rsaJWK) { 481 482 n = rsaJWK.n; 483 e = rsaJWK.e; 484 d = rsaJWK.d; 485 p = rsaJWK.p; 486 q = rsaJWK.q; 487 dp = rsaJWK.dp; 488 dq = rsaJWK.dq; 489 qi = rsaJWK.qi; 490 oth = rsaJWK.oth; 491 priv = rsaJWK.privateKey; 492 use = rsaJWK.getKeyUse(); 493 ops = rsaJWK.getKeyOperations(); 494 alg = rsaJWK.getAlgorithm(); 495 kid = rsaJWK.getKeyID(); 496 x5u = rsaJWK.getX509CertURL(); 497 x5t = rsaJWK.getX509CertThumbprint(); 498 x5c = rsaJWK.getX509CertChain(); 499 ks = rsaJWK.getKeyStore(); 500 } 501 502 503 /** 504 * Sets the private exponent ({@code d}) of the RSA key. 505 * 506 * @param d The private RSA key exponent. It is represented as 507 * the Base64URL encoding of the value's big endian 508 * representation. {@code null} if not specified (for 509 * a public key or a private key using the second 510 * representation only). 511 * 512 * @return This builder. 513 */ 514 public Builder privateExponent(final Base64URL d) { 515 516 this.d = d; 517 return this; 518 } 519 520 521 /** 522 * Sets the private RSA key, using the first representation. 523 * 524 * @param priv The private RSA key, used to obtain the private 525 * exponent ({@code d}). Must not be {@code null}. 526 * 527 * @return This builder. 528 */ 529 public Builder privateKey(final RSAPrivateKey priv) { 530 531 if (priv instanceof RSAPrivateCrtKey) { 532 return this.privateKey((RSAPrivateCrtKey) priv); 533 } else if (priv instanceof RSAMultiPrimePrivateCrtKey) { 534 return this.privateKey((RSAMultiPrimePrivateCrtKey) priv); 535 } else { 536 this.d = Base64URL.encode(priv.getPrivateExponent()); 537 return this; 538 } 539 } 540 541 542 /** 543 * Sets the private RSA key, typically for a key located in a 544 * PKCS#11 store that doesn't expose the private key parameters 545 * (such as a smart card or HSM). 546 * 547 * @param priv The private RSA key reference. Its algorithm 548 * must be "RSA". Must not be {@code null}. 549 * 550 * @return This builder. 551 */ 552 public Builder privateKey(final PrivateKey priv) { 553 554 if (! "RSA".equalsIgnoreCase(priv.getAlgorithm())) { 555 throw new IllegalArgumentException("The private key algorithm must be RSA"); 556 } 557 558 this.priv = priv; 559 return this; 560 } 561 562 563 /** 564 * Sets the first prime factor ({@code p}) of the private RSA 565 * key. 566 * 567 * @param p The RSA first prime factor. It is represented as 568 * the Base64URL encoding of the value's big endian 569 * representation. {@code null} if not specified (for 570 * a public key or a private key using the first 571 * representation only). 572 * 573 * @return This builder. 574 */ 575 public Builder firstPrimeFactor(final Base64URL p) { 576 577 this.p = p; 578 return this; 579 } 580 581 582 /** 583 * Sets the second prime factor ({@code q}) of the private RSA 584 * key. 585 * 586 * @param q The RSA second prime factor. It is represented as 587 * the Base64URL encoding of the value's big endian 588 * representation. {@code null} if not specified (for 589 * a public key or a private key using the first 590 * representation only). 591 * 592 * @return This builder. 593 */ 594 public Builder secondPrimeFactor(final Base64URL q) { 595 596 this.q = q; 597 return this; 598 } 599 600 601 /** 602 * Sets the first factor Chinese Remainder Theorem (CRT) 603 * exponent ({@code dp}) of the private RSA key. 604 * 605 * @param dp The RSA first factor CRT exponent. It is 606 * represented as the Base64URL encoding of the 607 * value's big endian representation. {@code null} 608 * if not specified (for a public key or a private 609 * key using the first representation only). 610 * 611 * @return This builder. 612 */ 613 public Builder firstFactorCRTExponent(final Base64URL dp) { 614 615 this.dp = dp; 616 return this; 617 } 618 619 620 /** 621 * Sets the second factor Chinese Remainder Theorem (CRT) 622 * exponent ({@code dq}) of the private RSA key. 623 * 624 * @param dq The RSA second factor CRT exponent. It is 625 * represented as the Base64URL encoding of the 626 * value's big endian representation. {@code null} if 627 * not specified (for a public key or a private key 628 * using the first representation only). 629 * 630 * @return This builder. 631 */ 632 public Builder secondFactorCRTExponent(final Base64URL dq) { 633 634 this.dq = dq; 635 return this; 636 } 637 638 639 /** 640 * Sets the first Chinese Remainder Theorem (CRT) coefficient 641 * ({@code qi})} of the private RSA key. 642 * 643 * @param qi The RSA first CRT coefficient. It is represented 644 * as the Base64URL encoding of the value's big 645 * endian representation. {@code null} if not 646 * specified (for a public key or a private key using 647 * the first representation only). 648 * 649 * @return This builder. 650 */ 651 public Builder firstCRTCoefficient(final Base64URL qi) { 652 653 this.qi = qi; 654 return this; 655 } 656 657 658 /** 659 * Sets the other primes information ({@code oth}) for the 660 * private RSA key, should they exist. 661 * 662 * @param oth The RSA other primes information, {@code null} or 663 * empty list if not specified. 664 * 665 * @return This builder. 666 */ 667 public Builder otherPrimes(final List<OtherPrimesInfo> oth) { 668 669 this.oth = oth; 670 return this; 671 } 672 673 674 /** 675 * Sets the private RSA key, using the second representation 676 * (see RFC 3447, section 3.2). 677 * 678 * @param priv The private RSA key, used to obtain the private 679 * exponent ({@code d}), the first prime factor 680 * ({@code p}), the second prime factor 681 * ({@code q}), the first factor CRT exponent 682 * ({@code dp}), the second factor CRT exponent 683 * ({@code dq}) and the first CRT coefficient 684 * ({@code qi}). Must not be {@code null}. 685 * 686 * @return This builder. 687 */ 688 public Builder privateKey(final RSAPrivateCrtKey priv) { 689 690 d = Base64URL.encode(priv.getPrivateExponent()); 691 p = Base64URL.encode(priv.getPrimeP()); 692 q = Base64URL.encode(priv.getPrimeQ()); 693 dp = Base64URL.encode(priv.getPrimeExponentP()); 694 dq = Base64URL.encode(priv.getPrimeExponentQ()); 695 qi = Base64URL.encode(priv.getCrtCoefficient()); 696 697 return this; 698 } 699 700 701 /** 702 * Sets the private RSA key, using the second representation, 703 * with optional other primes info (see RFC 3447, section 3.2). 704 * 705 * @param priv The private RSA key, used to obtain the private 706 * exponent ({@code d}), the first prime factor 707 * ({@code p}), the second prime factor 708 * ({@code q}), the first factor CRT exponent 709 * ({@code dp}), the second factor CRT exponent 710 * ({@code dq}), the first CRT coefficient 711 * ({@code qi}) and the other primes info 712 * ({@code oth}). Must not be {@code null}. 713 * 714 * @return This builder. 715 */ 716 public Builder privateKey(final RSAMultiPrimePrivateCrtKey priv) { 717 718 d = Base64URL.encode(priv.getPrivateExponent()); 719 p = Base64URL.encode(priv.getPrimeP()); 720 q = Base64URL.encode(priv.getPrimeQ()); 721 dp = Base64URL.encode(priv.getPrimeExponentP()); 722 dq = Base64URL.encode(priv.getPrimeExponentQ()); 723 qi = Base64URL.encode(priv.getCrtCoefficient()); 724 oth = OtherPrimesInfo.toList(priv.getOtherPrimeInfo()); 725 726 return this; 727 } 728 729 730 /** 731 * Sets the use ({@code use}) of the JWK. 732 * 733 * @param use The key use, {@code null} if not specified or if 734 * the key is intended for signing as well as 735 * encryption. 736 * 737 * @return This builder. 738 */ 739 public Builder keyUse(final KeyUse use) { 740 741 this.use = use; 742 return this; 743 } 744 745 746 /** 747 * Sets the operations ({@code key_ops}) of the JWK (for a 748 * non-public key). 749 * 750 * @param ops The key operations, {@code null} if not 751 * specified. 752 * 753 * @return This builder. 754 */ 755 public Builder keyOperations(final Set<KeyOperation> ops) { 756 757 this.ops = ops; 758 return this; 759 } 760 761 762 /** 763 * Sets the intended JOSE algorithm ({@code alg}) for the JWK. 764 * 765 * @param alg The intended JOSE algorithm, {@code null} if not 766 * specified. 767 * 768 * @return This builder. 769 */ 770 public Builder algorithm(final Algorithm alg) { 771 772 this.alg = alg; 773 return this; 774 } 775 776 /** 777 * Sets the ID ({@code kid}) of the JWK. The key ID can be used 778 * to match a specific key. This can be used, for instance, to 779 * choose a key within a {@link JWKSet} during key rollover. 780 * The key ID may also correspond to a JWS/JWE {@code kid} 781 * header parameter value. 782 * 783 * @param kid The key ID, {@code null} if not specified. 784 * 785 * @return This builder. 786 */ 787 public Builder keyID(final String kid) { 788 789 this.kid = kid; 790 return this; 791 } 792 793 794 /** 795 * Sets the ID ({@code kid}) of the JWK to its SHA-256 JWK 796 * thumbprint (RFC 7638). The key ID can be used to match a 797 * specific key. This can be used, for instance, to choose a 798 * key within a {@link JWKSet} during key rollover. The key ID 799 * may also correspond to a JWS/JWE {@code kid} header 800 * parameter value. 801 * 802 * @return This builder. 803 * 804 * @throws JOSEException If the SHA-256 hash algorithm is not 805 * supported. 806 */ 807 public Builder keyIDFromThumbprint() 808 throws JOSEException { 809 810 return keyIDFromThumbprint("SHA-256"); 811 } 812 813 814 /** 815 * Sets the ID ({@code kid}) of the JWK to its JWK thumbprint 816 * (RFC 7638). The key ID can be used to match a specific key. 817 * This can be used, for instance, to choose a key within a 818 * {@link JWKSet} during key rollover. The key ID may also 819 * correspond to a JWS/JWE {@code kid} header parameter value. 820 * 821 * @param hashAlg The hash algorithm for the JWK thumbprint 822 * computation. Must not be {@code null}. 823 * 824 * @return This builder. 825 * 826 * @throws JOSEException If the hash algorithm is not 827 * supported. 828 */ 829 public Builder keyIDFromThumbprint(final String hashAlg) 830 throws JOSEException { 831 832 // Put mandatory params in sorted order 833 LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>(); 834 requiredParams.put("e", e.toString()); 835 requiredParams.put("kty", KeyType.RSA.getValue()); 836 requiredParams.put("n", n.toString()); 837 this.kid = ThumbprintUtils.compute(hashAlg, requiredParams).toString(); 838 return this; 839 } 840 841 842 /** 843 * Sets the X.509 certificate URL ({@code x5u}) of the JWK. 844 * 845 * @param x5u The X.509 certificate URL, {@code null} if not 846 * specified. 847 * 848 * @return This builder. 849 */ 850 public Builder x509CertURL(final URI x5u) { 851 852 this.x5u = x5u; 853 return this; 854 } 855 856 857 /** 858 * Sets the X.509 certificate thumbprint ({@code x5t}) of the 859 * JWK. 860 * 861 * @param x5t The X.509 certificate thumbprint, {@code null} if 862 * not specified. 863 * 864 * @return This builder. 865 */ 866 public Builder x509CertThumbprint(final Base64URL x5t) { 867 868 this.x5t = x5t; 869 return this; 870 } 871 872 /** 873 * Sets the X.509 certificate chain ({@code x5c}) of the JWK. 874 * 875 * @param x5c The X.509 certificate chain as a unmodifiable 876 * list, {@code null} if not specified. 877 * 878 * @return This builder. 879 */ 880 public Builder x509CertChain(final List<Base64> x5c) { 881 882 this.x5c = x5c; 883 return this; 884 } 885 886 887 /** 888 * Sets the underlying key store. 889 * 890 * @param keyStore Reference to the underlying key store, 891 * {@code null} if none. 892 * 893 * @return This builder. 894 */ 895 public Builder keyStore(final KeyStore keyStore) { 896 897 this.ks = keyStore; 898 return this; 899 } 900 901 902 /** 903 * Builds a new RSA JWK. 904 * 905 * @return The RSA JWK. 906 * 907 * @throws IllegalStateException If the JWK parameters were 908 * inconsistently specified. 909 */ 910 public RSAKey build() { 911 912 try { 913 // The full constructor 914 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, 915 priv, 916 use, ops, alg, kid, x5u, x5t, x5c, 917 ks); 918 919 } catch (IllegalArgumentException e) { 920 921 throw new IllegalStateException(e.getMessage(), e); 922 } 923 } 924 } 925 926 927 // Public RSA params 928 929 /** 930 * The modulus value of the RSA key. 931 */ 932 private final Base64URL n; 933 934 935 /** 936 * The public exponent of the RSA key. 937 */ 938 private final Base64URL e; 939 940 941 // Private RSA params, 1st representation 942 943 /** 944 * The private exponent of the RSA key. 945 */ 946 private final Base64URL d; 947 948 949 // Private RSA params, 2nd representation 950 951 /** 952 * The first prime factor of the private RSA key. 953 */ 954 private final Base64URL p; 955 956 957 /** 958 * The second prime factor of the private RSA key. 959 */ 960 private final Base64URL q; 961 962 963 /** 964 * The first factor Chinese Remainder Theorem exponent of the private 965 * RSA key. 966 */ 967 private final Base64URL dp; 968 969 970 /** 971 * The second factor Chinese Remainder Theorem exponent of the private 972 * RSA key. 973 */ 974 private final Base64URL dq; 975 976 977 /** 978 * The first Chinese Remainder Theorem coefficient of the private RSA 979 * key. 980 */ 981 private final Base64URL qi; 982 983 984 /** 985 * The other primes information of the private RSA key, should they 986 * exist. When only two primes have been used (the normal case), this 987 * parameter MUST be omitted. When three or more primes have been used, 988 * the number of array elements MUST be the number of primes used minus 989 * two. 990 */ 991 private final List<OtherPrimesInfo> oth; 992 993 994 // Private RSA PKCS#11 key handle 995 996 /** 997 * Private PKCS#11 key handle. 998 */ 999 private final PrivateKey privateKey; 1000 1001 1002 /** 1003 * Creates a new public RSA JSON Web Key (JWK) with the specified 1004 * parameters. 1005 * 1006 * @param n The the modulus value for the public RSA key. It is 1007 * represented as the Base64URL encoding of value's big 1008 * endian representation. Must not be {@code null}. 1009 * @param e The exponent value for the public RSA key. It is 1010 * represented as the Base64URL encoding of value's big 1011 * endian representation. Must not be {@code null}. 1012 * @param use The key use, {@code null} if not specified or if the key 1013 * is intended for signing as well as encryption. 1014 * @param ops The key operations, {@code null} if not specified. 1015 * @param alg The intended JOSE algorithm for the key, {@code null} if 1016 * not specified. 1017 * @param kid The key ID. {@code null} if not specified. 1018 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1019 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1020 * specified. 1021 * @param x5c The X.509 certificate chain, {@code null} if not 1022 * specified. 1023 * @param ks Reference to the underlying key store, {@code null} if 1024 * not specified. 1025 */ 1026 public RSAKey(final Base64URL n, final Base64URL e, 1027 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1028 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1029 final KeyStore ks) { 1030 1031 // Call the full constructor, all private key parameters are null 1032 this(n, e, null, null, null, null, null, null, null, null, use, ops, alg, kid, 1033 x5u, x5t, x5c, 1034 ks); 1035 } 1036 1037 1038 /** 1039 * Creates a new public / private RSA JSON Web Key (JWK) with the 1040 * specified parameters. The private RSA key is specified by its first 1041 * representation (see RFC 3447, section 3.2). 1042 * 1043 * @param n The the modulus value for the public RSA key. It is 1044 * represented as the Base64URL encoding of value's big 1045 * endian representation. Must not be {@code null}. 1046 * @param e The exponent value for the public RSA key. It is 1047 * represented as the Base64URL encoding of value's big 1048 * endian representation. Must not be {@code null}. 1049 * @param d The private exponent. It is represented as the Base64URL 1050 * encoding of the value's big endian representation. Must 1051 * not be {@code null}. 1052 * @param use The key use, {@code null} if not specified or if the key 1053 * is intended for signing as well as encryption. 1054 * @param ops The key operations, {@code null} if not specified. 1055 * @param alg The intended JOSE algorithm for the key, {@code null} if 1056 * not specified. 1057 * @param kid The key ID. {@code null} if not specified. 1058 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1059 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1060 * specified. 1061 * @param x5c The X.509 certificate chain, {@code null} if not 1062 * specified. 1063 * @param ks Reference to the underlying key store, {@code null} if 1064 * not specified. 1065 */ 1066 public RSAKey(final Base64URL n, final Base64URL e, final Base64URL d, 1067 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1068 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1069 final KeyStore ks) { 1070 1071 // Call the full constructor, the second private representation 1072 // parameters are all null 1073 this(n, e, d, null, null, null, null, null, null, null, use, ops, alg, kid, 1074 x5u, x5t, x5c, ks); 1075 1076 if (d == null) { 1077 throw new IllegalArgumentException("The private exponent must not be null"); 1078 } 1079 } 1080 1081 1082 /** 1083 * Creates a new public / private RSA JSON Web Key (JWK) with the 1084 * specified parameters. The private RSA key is specified by its 1085 * second representation (see RFC 3447, section 3.2). 1086 * 1087 * @param n The the modulus value for the public RSA key. It is 1088 * represented as the Base64URL encoding of value's big 1089 * endian representation. Must not be {@code null}. 1090 * @param e The exponent value for the public RSA key. It is 1091 * represented as the Base64URL encoding of value's big 1092 * endian representation. Must not be {@code null}. 1093 * @param p The first prime factor. It is represented as the 1094 * Base64URL encoding of the value's big endian 1095 * representation. Must not be {@code null}. 1096 * @param q The second prime factor. It is represented as the 1097 * Base64URL encoding of the value's big endian 1098 * representation. Must not be {@code null}. 1099 * @param dp The first factor Chinese Remainder Theorem exponent. It 1100 * is represented as the Base64URL encoding of the value's 1101 * big endian representation. Must not be {@code null}. 1102 * @param dq The second factor Chinese Remainder Theorem exponent. It 1103 * is represented as the Base64URL encoding of the value's 1104 * big endian representation. Must not be {@code null}. 1105 * @param qi The first Chinese Remainder Theorem coefficient. It is 1106 * represented as the Base64URL encoding of the value's big 1107 * endian representation. Must not be {@code null}. 1108 * @param oth The other primes information, should they exist, 1109 * {@code null} or an empty list if not specified. 1110 * @param use The key use, {@code null} if not specified or if the key 1111 * is intended for signing as well as encryption. 1112 * @param ops The key operations, {@code null} if not specified. 1113 * @param alg The intended JOSE algorithm for the key, {@code null} if 1114 * not specified. 1115 * @param kid The key ID. {@code null} if not specified. 1116 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1117 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1118 * specified. 1119 * @param x5c The X.509 certificate chain, {@code null} if not 1120 * specified. 1121 * @param ks Reference to the underlying key store, {@code null} if 1122 * not specified. 1123 */ 1124 public RSAKey(final Base64URL n, final Base64URL e, 1125 final Base64URL p, final Base64URL q, 1126 final Base64URL dp, final Base64URL dq, final Base64URL qi, 1127 final List<OtherPrimesInfo> oth, 1128 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1129 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1130 final KeyStore ks) { 1131 1132 // Call the full constructor, the first private representation 1133 // d param is null 1134 this(n, e, null, p, q, dp, dq, qi, oth, null, use, ops, alg, kid, 1135 x5u, x5t, x5c, 1136 ks); 1137 1138 if (p == null) { 1139 throw new IllegalArgumentException("The first prime factor must not be null"); 1140 } 1141 1142 if (q == null) { 1143 throw new IllegalArgumentException("The second prime factor must not be null"); 1144 } 1145 1146 if (dp == null) { 1147 throw new IllegalArgumentException("The first factor CRT exponent must not be null"); 1148 } 1149 1150 if (dq == null) { 1151 throw new IllegalArgumentException("The second factor CRT exponent must not be null"); 1152 } 1153 1154 if (qi == null) { 1155 throw new IllegalArgumentException("The first CRT coefficient must not be null"); 1156 } 1157 } 1158 1159 1160 /** 1161 * Creates a new public / private RSA JSON Web Key (JWK) with the 1162 * specified parameters. The private RSA key is specified by both its 1163 * first and second representations (see RFC 3447, section 3.2). 1164 * 1165 * <p>A valid first private RSA key representation must specify the 1166 * {@code d} parameter. 1167 * 1168 * <p>A valid second private RSA key representation must specify all 1169 * required Chinese Remainder Theorem (CRT) parameters - {@code p}, 1170 * {@code q}, {@code dp}, {@code dq} and {@code qi}, else an 1171 * {@link java.lang.IllegalArgumentException} will be thrown. 1172 * 1173 * @param n The the modulus value for the public RSA key. It is 1174 * represented as the Base64URL encoding of value's big 1175 * endian representation. Must not be {@code null}. 1176 * @param e The exponent value for the public RSA key. It is 1177 * represented as the Base64URL encoding of value's big 1178 * endian representation. Must not be {@code null}. 1179 * @param d The private exponent. It is represented as the Base64URL 1180 * encoding of the value's big endian representation. May 1181 * be {@code null}. 1182 * @param p The first prime factor. It is represented as the 1183 * Base64URL encoding of the value's big endian 1184 * representation. May be {@code null}. 1185 * @param q The second prime factor. It is represented as the 1186 * Base64URL encoding of the value's big endian 1187 * representation. May be {@code null}. 1188 * @param dp The first factor Chinese Remainder Theorem exponent. It 1189 * is represented as the Base64URL encoding of the value's 1190 * big endian representation. May be {@code null}. 1191 * @param dq The second factor Chinese Remainder Theorem exponent. It 1192 * is represented as the Base64URL encoding of the value's 1193 * big endian representation. May be {@code null}. 1194 * @param qi The first Chinese Remainder Theorem coefficient. It is 1195 * represented as the Base64URL encoding of the value's big 1196 * endian representation. May be {@code null}. 1197 * @param oth The other primes information, should they exist, 1198 * {@code null} or an empty list if not specified. 1199 * @param use The key use, {@code null} if not specified or if the key 1200 * is intended for signing as well as encryption. 1201 * @param ops The key operations, {@code null} if not specified. 1202 * @param alg The intended JOSE algorithm for the key, {@code null} if 1203 * not specified. 1204 * @param kid The key ID. {@code null} if not specified. 1205 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1206 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1207 * specified. 1208 * @param x5c The X.509 certificate chain, {@code null} if not 1209 * specified. 1210 */ 1211 @Deprecated 1212 public RSAKey(final Base64URL n, final Base64URL e, 1213 final Base64URL d, 1214 final Base64URL p, final Base64URL q, 1215 final Base64URL dp, final Base64URL dq, final Base64URL qi, 1216 final List<OtherPrimesInfo> oth, 1217 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1218 final URI x5u, final Base64URL x5t, final List<Base64> x5c) { 1219 1220 this(n, e, d, p, q, dp, dq, qi, oth, null, use, ops, alg, kid, x5u, x5t, x5c, null); 1221 } 1222 1223 1224 /** 1225 * Creates a new public / private RSA JSON Web Key (JWK) with the 1226 * specified parameters. The private RSA key can be specified by its 1227 * first representation, its second representation (see RFC 3447, 1228 * section 3.2), or by a PKCS#11 handle as {@link PrivateKey}. 1229 * 1230 * <p>A valid first private RSA key representation must specify the 1231 * {@code d} parameter. 1232 * 1233 * <p>A valid second private RSA key representation must specify all 1234 * required Chinese Remainder Theorem (CRT) parameters - {@code p}, 1235 * {@code q}, {@code dp}, {@code dq} and {@code qi}, else an 1236 * {@link java.lang.IllegalArgumentException} will be thrown. 1237 * 1238 * @param n The the modulus value for the public RSA key. It is 1239 * represented as the Base64URL encoding of value's big 1240 * endian representation. Must not be {@code null}. 1241 * @param e The exponent value for the public RSA key. It is 1242 * represented as the Base64URL encoding of value's big 1243 * endian representation. Must not be {@code null}. 1244 * @param d The private exponent. It is represented as the Base64URL 1245 * encoding of the value's big endian representation. May 1246 * be {@code null}. 1247 * @param p The first prime factor. It is represented as the 1248 * Base64URL encoding of the value's big endian 1249 * representation. May be {@code null}. 1250 * @param q The second prime factor. It is represented as the 1251 * Base64URL encoding of the value's big endian 1252 * representation. May be {@code null}. 1253 * @param dp The first factor Chinese Remainder Theorem exponent. It 1254 * is represented as the Base64URL encoding of the value's 1255 * big endian representation. May be {@code null}. 1256 * @param dq The second factor Chinese Remainder Theorem exponent. It 1257 * is represented as the Base64URL encoding of the value's 1258 * big endian representation. May be {@code null}. 1259 * @param qi The first Chinese Remainder Theorem coefficient. It is 1260 * represented as the Base64URL encoding of the value's big 1261 * endian representation. May be {@code null}. 1262 * @param oth The other primes information, should they exist, 1263 * {@code null} or an empty list if not specified. 1264 * @param prv The private key as a PKCS#11 handle, {@code null} if not 1265 * specified. 1266 * @param use The key use, {@code null} if not specified or if the key 1267 * is intended for signing as well as encryption. 1268 * @param ops The key operations, {@code null} if not specified. 1269 * @param alg The intended JOSE algorithm for the key, {@code null} if 1270 * not specified. 1271 * @param kid The key ID. {@code null} if not specified. 1272 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1273 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1274 * specified. 1275 * @param x5c The X.509 certificate chain, {@code null} if not 1276 * specified. 1277 * @param ks Reference to the underlying key store, {@code null} if 1278 * not specified. 1279 */ 1280 public RSAKey(final Base64URL n, final Base64URL e, 1281 final Base64URL d, 1282 final Base64URL p, final Base64URL q, 1283 final Base64URL dp, final Base64URL dq, final Base64URL qi, 1284 final List<OtherPrimesInfo> oth, 1285 final PrivateKey prv, 1286 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1287 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1288 final KeyStore ks) { 1289 1290 super(KeyType.RSA, use, ops, alg, kid, x5u, x5t, x5c, ks); 1291 1292 1293 // Ensure the public params are defined 1294 1295 if (n == null) { 1296 throw new IllegalArgumentException("The modulus value must not be null"); 1297 } 1298 1299 this.n = n; 1300 1301 1302 if (e == null) { 1303 throw new IllegalArgumentException("The public exponent value must not be null"); 1304 } 1305 1306 this.e = e; 1307 1308 1309 // Private params, 1st representation 1310 1311 this.d = d; 1312 1313 1314 // Private params, 2nd representation, check for consistency 1315 1316 if (p != null && q != null && dp != null && dq != null && qi != null) { 1317 1318 // CRT params fully specified 1319 this.p = p; 1320 this.q = q; 1321 this.dp = dp; 1322 this.dq = dq; 1323 this.qi = qi; 1324 1325 // Other RSA primes info optional, default to empty list 1326 if (oth != null) { 1327 this.oth = Collections.unmodifiableList(oth); 1328 } else { 1329 this.oth = Collections.emptyList(); 1330 } 1331 1332 } else if (p == null && q == null && dp == null && dq == null && qi == null && oth == null) { 1333 1334 // No CRT params 1335 this.p = null; 1336 this.q = null; 1337 this.dp = null; 1338 this.dq = null; 1339 this.qi = null; 1340 1341 this.oth = Collections.emptyList(); 1342 1343 } else if (p != null || q != null || dp != null || dq != null || qi != null) { 1344 1345 if (p == null) { 1346 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first prime factor must not be null"); 1347 } else if (q == null) { 1348 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second prime factor must not be null"); 1349 } else if (dp == null) { 1350 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first factor CRT exponent must not be null"); 1351 } else if (dq == null) { 1352 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second factor CRT exponent must not be null"); 1353 } else { 1354 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first CRT coefficient must not be null"); 1355 } 1356 } else { 1357 // No CRT params 1358 this.p = null; 1359 this.q = null; 1360 this.dp = null; 1361 this.dq = null; 1362 this.qi = null; 1363 this.oth = Collections.emptyList(); 1364 } 1365 1366 this.privateKey = prv; // PKCS#11 handle 1367 } 1368 1369 1370 /** 1371 * Creates a new public RSA JSON Web Key (JWK) with the specified 1372 * parameters. 1373 * 1374 * @param pub The public RSA key to represent. Must not be 1375 * {@code null}. 1376 * @param use The key use, {@code null} if not specified or if the key 1377 * is intended for signing as well as encryption. 1378 * @param ops The key operations, {@code null} if not specified. 1379 * @param alg The intended JOSE algorithm for the key, {@code null} if 1380 * not specified. 1381 * @param kid The key ID. {@code null} if not specified. 1382 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1383 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1384 * specified. 1385 * @param x5c The X.509 certificate chain, {@code null} if not 1386 * specified. 1387 * @param ks Reference to the underlying key store, {@code null} if 1388 * not specified. 1389 */ 1390 public RSAKey(final RSAPublicKey pub, 1391 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1392 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1393 final KeyStore ks) { 1394 1395 this(Base64URL.encode(pub.getModulus()), 1396 Base64URL.encode(pub.getPublicExponent()), 1397 use, ops, alg, kid, 1398 x5u, x5t, x5c, 1399 ks); 1400 } 1401 1402 1403 /** 1404 * Creates a new public / private RSA JSON Web Key (JWK) with the 1405 * specified parameters. The private RSA key is specified by its first 1406 * representation (see RFC 3447, section 3.2). 1407 * 1408 * @param pub The public RSA key to represent. Must not be 1409 * {@code null}. 1410 * @param priv The private RSA key to represent. Must not be 1411 * {@code null}. 1412 * @param use The key use, {@code null} if not specified or if the key 1413 * is intended for signing as well as encryption. 1414 * @param ops The key operations, {@code null} if not specified. 1415 * @param alg The intended JOSE algorithm for the key, {@code null} if 1416 * not specified. 1417 * @param kid The key ID. {@code null} if not specified. 1418 * @param x5u The X.509 certificate URL, {@code null} if not 1419 * specified. 1420 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1421 * specified. 1422 * @param x5c The X.509 certificate chain, {@code null} if not 1423 * specified. 1424 * @param ks Reference to the underlying key store, {@code null} if 1425 * not specified. 1426 */ 1427 public RSAKey(final RSAPublicKey pub, final RSAPrivateKey priv, 1428 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1429 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1430 final KeyStore ks) { 1431 1432 this(Base64URL.encode(pub.getModulus()), 1433 Base64URL.encode(pub.getPublicExponent()), 1434 Base64URL.encode(priv.getPrivateExponent()), 1435 use, ops, alg, kid, 1436 x5u, x5t, x5c, 1437 ks); 1438 } 1439 1440 1441 /** 1442 * Creates a new public / private RSA JSON Web Key (JWK) with the 1443 * specified parameters. The private RSA key is specified by its second 1444 * representation (see RFC 3447, section 3.2). 1445 * 1446 * @param pub The public RSA key to represent. Must not be 1447 * {@code null}. 1448 * @param priv The private RSA key to represent. Must not be 1449 * {@code null}. 1450 * @param use The key use, {@code null} if not specified or if the key 1451 * is intended for signing as well as encryption. 1452 * @param ops The key operations, {@code null} if not specified. 1453 * @param alg The intended JOSE algorithm for the key, {@code null} if 1454 * not specified. 1455 * @param kid The key ID. {@code null} if not specified. 1456 * @param x5u The X.509 certificate URL, {@code null} if not 1457 * specified. 1458 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1459 * specified. 1460 * @param x5c The X.509 certificate chain, {@code null} if not 1461 * specified. 1462 * @param ks Reference to the underlying key store, {@code null} if 1463 * not specified. 1464 */ 1465 public RSAKey(final RSAPublicKey pub, final RSAPrivateCrtKey priv, 1466 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1467 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1468 final KeyStore ks) { 1469 1470 this(Base64URL.encode(pub.getModulus()), 1471 Base64URL.encode(pub.getPublicExponent()), 1472 Base64URL.encode(priv.getPrivateExponent()), 1473 Base64URL.encode(priv.getPrimeP()), 1474 Base64URL.encode(priv.getPrimeQ()), 1475 Base64URL.encode(priv.getPrimeExponentP()), 1476 Base64URL.encode(priv.getPrimeExponentQ()), 1477 Base64URL.encode(priv.getCrtCoefficient()), 1478 null, 1479 null, 1480 use, ops, alg, kid, 1481 x5u, x5t, x5c, 1482 ks); 1483 } 1484 1485 1486 /** 1487 * Creates a new public / private RSA JSON Web Key (JWK) with the 1488 * specified parameters. The private RSA key is specified by its second 1489 * representation, with optional other primes info (see RFC 3447, 1490 * section 3.2). 1491 * 1492 * @param pub The public RSA key to represent. Must not be 1493 * {@code null}. 1494 * @param priv The private RSA key to represent. Must not be 1495 * {@code null}. 1496 * @param use The key use, {@code null} if not specified or if the key 1497 * is intended for signing as well as encryption. 1498 * @param ops The key operations, {@code null} if not specified. 1499 * @param alg The intended JOSE algorithm for the key, {@code null} if 1500 * not specified. 1501 * @param kid The key ID. {@code null} if not specified. 1502 * @param x5u The X.509 certificate URL, {@code null} if not 1503 * specified. 1504 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1505 * specified. 1506 * @param x5c The X.509 certificate chain, {@code null} if not 1507 * specified. 1508 * @param ks Reference to the underlying key store, {@code null} if 1509 * not specified. 1510 */ 1511 public RSAKey(final RSAPublicKey pub, final RSAMultiPrimePrivateCrtKey priv, 1512 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1513 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1514 final KeyStore ks) { 1515 1516 this(Base64URL.encode(pub.getModulus()), 1517 Base64URL.encode(pub.getPublicExponent()), 1518 Base64URL.encode(priv.getPrivateExponent()), 1519 Base64URL.encode(priv.getPrimeP()), 1520 Base64URL.encode(priv.getPrimeQ()), 1521 Base64URL.encode(priv.getPrimeExponentP()), 1522 Base64URL.encode(priv.getPrimeExponentQ()), 1523 Base64URL.encode(priv.getCrtCoefficient()), 1524 OtherPrimesInfo.toList(priv.getOtherPrimeInfo()), 1525 null, 1526 use, ops, alg, kid, 1527 x5u, x5t, x5c, 1528 ks); 1529 } 1530 1531 1532 /** 1533 * Creates a new public / private RSA JSON Web Key (JWK) with the 1534 * specified parameters. The private RSA key is specified by a PKCS#11 1535 * handle. 1536 * 1537 * @param pub The public RSA key to represent. Must not be 1538 * {@code null}. 1539 * @param priv The private RSA key as PKCS#11 handle, {@code null} if 1540 * not specified. 1541 * @param use The key use, {@code null} if not specified or if the key 1542 * is intended for signing as well as encryption. 1543 * @param ops The key operations, {@code null} if not specified. 1544 * @param alg The intended JOSE algorithm for the key, {@code null} if 1545 * not specified. 1546 * @param kid The key ID. {@code null} if not specified. 1547 * @param x5u The X.509 certificate URL, {@code null} if not 1548 * specified. 1549 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1550 * specified. 1551 * @param x5c The X.509 certificate chain, {@code null} if not 1552 * specified. 1553 * @param ks Reference to the underlying key store, {@code null} if 1554 * not specified. 1555 */ 1556 public RSAKey(final RSAPublicKey pub, final PrivateKey priv, 1557 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1558 final URI x5u, final Base64URL x5t, final List<Base64> x5c, 1559 final KeyStore ks) { 1560 1561 this(Base64URL.encode(pub.getModulus()), 1562 Base64URL.encode(pub.getPublicExponent()), 1563 null, 1564 null, 1565 null, 1566 null, 1567 null, 1568 null, 1569 null, 1570 priv, 1571 use, ops, alg, kid, 1572 x5u, x5t, x5c, 1573 ks); 1574 } 1575 1576 1577 /** 1578 * Gets the modulus value ({@code n}) of the RSA key. 1579 * 1580 * @return The RSA key modulus. It is represented as the Base64URL 1581 * encoding of the value's big endian representation. 1582 */ 1583 public Base64URL getModulus() { 1584 1585 return n; 1586 } 1587 1588 1589 /** 1590 * Gets the public exponent ({@code e}) of the RSA key. 1591 * 1592 * @return The public RSA key exponent. It is represented as the 1593 * Base64URL encoding of the value's big endian representation. 1594 */ 1595 public Base64URL getPublicExponent() { 1596 1597 return e; 1598 } 1599 1600 1601 /** 1602 * Gets the private exponent ({@code d}) of the RSA key. 1603 * 1604 * @return The private RSA key exponent. It is represented as the 1605 * Base64URL encoding of the value's big endian representation. 1606 * {@code null} if not specified (for a public key or a private 1607 * key using the second representation only). 1608 */ 1609 public Base64URL getPrivateExponent() { 1610 1611 return d; 1612 } 1613 1614 1615 /** 1616 * Gets the first prime factor ({@code p}) of the private RSA key. 1617 * 1618 * @return The RSA first prime factor. It is represented as the 1619 * Base64URL encoding of the value's big endian representation. 1620 * {@code null} if not specified (for a public key or a private 1621 * key using the first representation only). 1622 */ 1623 public Base64URL getFirstPrimeFactor() { 1624 1625 return p; 1626 } 1627 1628 1629 /** 1630 * Gets the second prime factor ({@code q}) of the private RSA key. 1631 * 1632 * @return The RSA second prime factor. It is represented as the 1633 * Base64URL encoding of the value's big endian representation. 1634 * {@code null} if not specified (for a public key or a private 1635 * key using the first representation only). 1636 */ 1637 public Base64URL getSecondPrimeFactor() { 1638 1639 return q; 1640 } 1641 1642 1643 /** 1644 * Gets the first factor Chinese Remainder Theorem (CRT) exponent 1645 * ({@code dp}) of the private RSA key. 1646 * 1647 * @return The RSA first factor CRT exponent. It is represented as the 1648 * Base64URL encoding of the value's big endian representation. 1649 * {@code null} if not specified (for a public key or a private 1650 * key using the first representation only). 1651 */ 1652 public Base64URL getFirstFactorCRTExponent() { 1653 1654 return dp; 1655 } 1656 1657 1658 /** 1659 * Gets the second factor Chinese Remainder Theorem (CRT) exponent 1660 * ({@code dq}) of the private RSA key. 1661 * 1662 * @return The RSA second factor CRT exponent. It is represented as the 1663 * Base64URL encoding of the value's big endian representation. 1664 * {@code null} if not specified (for a public key or a private 1665 * key using the first representation only). 1666 */ 1667 public Base64URL getSecondFactorCRTExponent() { 1668 1669 return dq; 1670 } 1671 1672 1673 /** 1674 * Gets the first Chinese Remainder Theorem (CRT) coefficient 1675 * ({@code qi})} of the private RSA key. 1676 * 1677 * @return The RSA first CRT coefficient. It is represented as the 1678 * Base64URL encoding of the value's big endian representation. 1679 * {@code null} if not specified (for a public key or a private 1680 * key using the first representation only). 1681 */ 1682 public Base64URL getFirstCRTCoefficient() { 1683 1684 return qi; 1685 } 1686 1687 1688 /** 1689 * Gets the other primes information ({@code oth}) for the private RSA 1690 * key, should they exist. 1691 * 1692 * @return The RSA other primes information, {@code null} or empty list 1693 * if not specified. 1694 */ 1695 public List<OtherPrimesInfo> getOtherPrimes() { 1696 1697 return oth; 1698 } 1699 1700 1701 /** 1702 * Returns a standard {@code java.security.interfaces.RSAPublicKey} 1703 * representation of this RSA JWK. 1704 * 1705 * @return The public RSA key. 1706 * 1707 * @throws JOSEException If RSA is not supported by the underlying Java 1708 * Cryptography (JCA) provider or if the JWK 1709 * parameters are invalid for a public RSA key. 1710 */ 1711 public RSAPublicKey toRSAPublicKey() 1712 throws JOSEException { 1713 1714 BigInteger modulus = n.decodeToBigInteger(); 1715 BigInteger exponent = e.decodeToBigInteger(); 1716 1717 RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent); 1718 1719 try { 1720 KeyFactory factory = KeyFactory.getInstance("RSA"); 1721 1722 return (RSAPublicKey) factory.generatePublic(spec); 1723 1724 } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { 1725 1726 throw new JOSEException(e.getMessage(), e); 1727 } 1728 } 1729 1730 1731 /** 1732 * Returns a standard {@code java.security.interfaces.RSAPrivateKey} 1733 * representation of this RSA JWK. 1734 * 1735 * @return The private RSA key, {@code null} if not specified by this 1736 * JWK. 1737 * 1738 * @throws JOSEException If RSA is not supported by the underlying Java 1739 * Cryptography (JCA) provider or if the JWK 1740 * parameters are invalid for a private RSA key. 1741 */ 1742 public RSAPrivateKey toRSAPrivateKey() 1743 throws JOSEException { 1744 1745 if (d == null) { 1746 // no private key 1747 return null; 1748 } 1749 1750 BigInteger modulus = n.decodeToBigInteger(); 1751 BigInteger privateExponent = d.decodeToBigInteger(); 1752 1753 RSAPrivateKeySpec spec; 1754 1755 if (p == null) { 1756 // Use 1st representation 1757 spec = new RSAPrivateKeySpec(modulus, privateExponent); 1758 1759 } else { 1760 // Use 2nd (CRT) representation 1761 BigInteger publicExponent = e.decodeToBigInteger(); 1762 BigInteger primeP = p.decodeToBigInteger(); 1763 BigInteger primeQ = q.decodeToBigInteger(); 1764 BigInteger primeExponentP = dp.decodeToBigInteger(); 1765 BigInteger primeExponentQ = dq.decodeToBigInteger(); 1766 BigInteger crtCoefficient = qi.decodeToBigInteger(); 1767 1768 if (oth != null && ! oth.isEmpty()) { 1769 // Construct other info spec 1770 RSAOtherPrimeInfo[] otherInfo = new RSAOtherPrimeInfo[oth.size()]; 1771 1772 for (int i=0; i < oth.size(); i++) { 1773 1774 OtherPrimesInfo opi = oth.get(i); 1775 1776 BigInteger otherPrime = opi.getPrimeFactor().decodeToBigInteger(); 1777 BigInteger otherPrimeExponent = opi.getFactorCRTExponent().decodeToBigInteger(); 1778 BigInteger otherCrtCoefficient = opi.getFactorCRTCoefficient().decodeToBigInteger(); 1779 1780 otherInfo[i] = new RSAOtherPrimeInfo(otherPrime, 1781 otherPrimeExponent, 1782 otherCrtCoefficient); 1783 } 1784 1785 spec = new RSAMultiPrimePrivateCrtKeySpec(modulus, 1786 publicExponent, 1787 privateExponent, 1788 primeP, 1789 primeQ, 1790 primeExponentP, 1791 primeExponentQ, 1792 crtCoefficient, 1793 otherInfo); 1794 } else { 1795 // Construct spec with no other info 1796 spec = new RSAPrivateCrtKeySpec(modulus, 1797 publicExponent, 1798 privateExponent, 1799 primeP, 1800 primeQ, 1801 primeExponentP, 1802 primeExponentQ, 1803 crtCoefficient); 1804 } 1805 } 1806 1807 try { 1808 KeyFactory factory = KeyFactory.getInstance("RSA"); 1809 1810 return (RSAPrivateKey) factory.generatePrivate(spec); 1811 1812 } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 1813 1814 throw new JOSEException(e.getMessage(), e); 1815 } 1816 } 1817 1818 1819 @Override 1820 public PublicKey toPublicKey() 1821 throws JOSEException { 1822 1823 return toRSAPublicKey(); 1824 } 1825 1826 1827 @Override 1828 public PrivateKey toPrivateKey() 1829 throws JOSEException { 1830 1831 PrivateKey prv = toRSAPrivateKey(); 1832 1833 if (prv != null) { 1834 // Return private RSA key with key material 1835 return prv; 1836 } 1837 1838 // Return private RSA key as PKCS#11 handle, or null 1839 return privateKey; 1840 } 1841 1842 1843 /** 1844 * Returns a standard {@code java.security.KeyPair} representation of 1845 * this RSA JWK. 1846 * 1847 * @return The RSA key pair. The private RSA key will be {@code null} 1848 * if not specified. 1849 * 1850 * @throws JOSEException If RSA is not supported by the underlying Java 1851 * Cryptography (JCA) provider or if the JWK 1852 * parameters are invalid for a public and / or 1853 * private RSA key. 1854 */ 1855 @Override 1856 public KeyPair toKeyPair() 1857 throws JOSEException { 1858 1859 return new KeyPair(toRSAPublicKey(), toPrivateKey()); 1860 } 1861 1862 1863 @Override 1864 public LinkedHashMap<String,?> getRequiredParams() { 1865 1866 // Put mandatory params in sorted order 1867 LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>(); 1868 requiredParams.put("e", e.toString()); 1869 requiredParams.put("kty", getKeyType().getValue()); 1870 requiredParams.put("n", n.toString()); 1871 return requiredParams; 1872 } 1873 1874 1875 @Override 1876 public boolean isPrivate() { 1877 1878 // Check if 1st or 2nd form params are specified, or PKCS#11 handle 1879 return d != null || p != null || privateKey != null; 1880 } 1881 1882 1883 @Override 1884 public int size() { 1885 1886 return ByteUtils.bitLength(n.decode()); 1887 } 1888 1889 1890 /** 1891 * Returns a copy of this RSA JWK with any private values removed. 1892 * 1893 * @return The copied public RSA JWK. 1894 */ 1895 @Override 1896 public RSAKey toPublicJWK() { 1897 1898 return new RSAKey( 1899 getModulus(), getPublicExponent(), 1900 getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(), 1901 getX509CertURL(), getX509CertThumbprint(), getX509CertChain(), 1902 getKeyStore()); 1903 } 1904 1905 1906 @Override 1907 public JSONObject toJSONObject() { 1908 1909 JSONObject o = super.toJSONObject(); 1910 1911 // Append public RSA key specific attributes 1912 o.put("n", n.toString()); 1913 o.put("e", e.toString()); 1914 if (d != null) { 1915 o.put("d", d.toString()); 1916 } 1917 if (p != null) { 1918 o.put("p", p.toString()); 1919 } 1920 if (q != null) { 1921 o.put("q", q.toString()); 1922 } 1923 if (dp != null) { 1924 o.put("dp", dp.toString()); 1925 } 1926 if (dq != null) { 1927 o.put("dq", dq.toString()); 1928 } 1929 if (qi != null) { 1930 o.put("qi", qi.toString()); 1931 } 1932 if (oth != null && !oth.isEmpty()) { 1933 1934 JSONArray a = new JSONArray(); 1935 1936 for (OtherPrimesInfo other : oth) { 1937 1938 JSONObject oo = new JSONObject(); 1939 oo.put("r", other.r.toString()); 1940 oo.put("d", other.d.toString()); 1941 oo.put("t", other.t.toString()); 1942 1943 a.add(oo); 1944 } 1945 1946 o.put("oth", a); 1947 } 1948 1949 return o; 1950 } 1951 1952 1953 /** 1954 * Parses a public / private RSA JWK from the specified JSON object 1955 * string representation. 1956 * 1957 * @param s The JSON object string to parse. Must not be {@code null}. 1958 * 1959 * @return The public / private RSA JWK. 1960 * 1961 * @throws ParseException If the string couldn't be parsed to an RSA 1962 * JWK. 1963 */ 1964 public static RSAKey parse(final String s) 1965 throws ParseException { 1966 1967 return parse(JSONObjectUtils.parse(s)); 1968 } 1969 1970 1971 /** 1972 * Parses a public / private RSA JWK from the specified JSON object 1973 * representation. 1974 * 1975 * @param jsonObject The JSON object to parse. Must not be 1976 * {@code null}. 1977 * 1978 * @return The public / private RSA Key. 1979 * 1980 * @throws ParseException If the JSON object couldn't be parsed to an 1981 * RSA JWK. 1982 */ 1983 public static RSAKey parse(final JSONObject jsonObject) 1984 throws ParseException { 1985 1986 // Parse the mandatory public key parameters first 1987 Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n")); 1988 Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e")); 1989 1990 // Check key type 1991 KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty")); 1992 if (kty != KeyType.RSA) { 1993 throw new ParseException("The key type \"kty\" must be RSA", 0); 1994 } 1995 1996 // Parse the optional private key parameters 1997 1998 // 1st private representation 1999 Base64URL d = null; 2000 if (jsonObject.containsKey("d")) { 2001 d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d")); 2002 } 2003 2004 // 2nd private (CRT) representation 2005 Base64URL p = null; 2006 if (jsonObject.containsKey("p")) { 2007 p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p")); 2008 } 2009 Base64URL q = null; 2010 if (jsonObject.containsKey("q")) { 2011 q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q")); 2012 } 2013 Base64URL dp = null; 2014 if (jsonObject.containsKey("dp")) { 2015 dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp")); 2016 } 2017 Base64URL dq= null; 2018 if (jsonObject.containsKey("dq")) { 2019 dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq")); 2020 } 2021 Base64URL qi = null; 2022 if (jsonObject.containsKey("qi")) { 2023 qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi")); 2024 } 2025 2026 List<OtherPrimesInfo> oth = null; 2027 if (jsonObject.containsKey("oth")) { 2028 2029 JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth"); 2030 oth = new ArrayList<>(arr.size()); 2031 2032 for (Object o : arr) { 2033 2034 if (o instanceof JSONObject) { 2035 JSONObject otherJson = (JSONObject)o; 2036 2037 Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r")); 2038 Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq")); 2039 Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t")); 2040 2041 OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t); 2042 oth.add(prime); 2043 } 2044 } 2045 } 2046 2047 try { 2048 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, null, 2049 JWKMetadata.parseKeyUse(jsonObject), 2050 JWKMetadata.parseKeyOperations(jsonObject), 2051 JWKMetadata.parseAlgorithm(jsonObject), 2052 JWKMetadata.parseKeyID(jsonObject), 2053 JWKMetadata.parseX509CertURL(jsonObject), 2054 JWKMetadata.parseX509CertThumbprint(jsonObject), 2055 JWKMetadata.parseX509CertChain(jsonObject), 2056 null); 2057 2058 } catch (IllegalArgumentException ex) { 2059 2060 // Inconsistent 2nd spec, conflicting 'use' and 'key_ops' 2061 throw new ParseException(ex.getMessage(), 0); 2062 } 2063 } 2064 2065 2066 /** 2067 * Parses a public RSA JWK from the specified X.509 certificate. 2068 * 2069 * <p><strong>Important:</strong> The X.509 certificate is not 2070 * validated! 2071 * 2072 * <p>Set the following JWK parameters: 2073 * 2074 * <ul> 2075 * <li>The JWK use inferred by {@link KeyUse#from}. 2076 * <li>The JWK ID from the X.509 serial number (in base 10). 2077 * <li>The JWK X.509 certificate chain (this certificate only). 2078 * <li>The JWK X.509 certificate SHA-1 thumbprint. 2079 * </ul> 2080 * 2081 * @param cert The X.509 certificate. Must not be {@code null}. 2082 * 2083 * @return The public RSA key. 2084 * 2085 * @throws JOSEException If parsing failed. 2086 */ 2087 public static RSAKey parse(final X509Certificate cert) 2088 throws JOSEException { 2089 2090 if (! (cert.getPublicKey() instanceof RSAPublicKey)) { 2091 throw new JOSEException("The public key of the X.509 certificate is not RSA"); 2092 } 2093 2094 RSAPublicKey publicKey = (RSAPublicKey)cert.getPublicKey(); 2095 2096 try { 2097 MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); 2098 2099 return new RSAKey.Builder(publicKey) 2100 .keyUse(KeyUse.from(cert)) 2101 .keyID(cert.getSerialNumber().toString(10)) 2102 .x509CertChain(Collections.singletonList(Base64.encode(cert.getEncoded()))) 2103 .x509CertThumbprint(Base64URL.encode(sha1.digest(cert.getEncoded()))) 2104 .build(); 2105 } catch (NoSuchAlgorithmException e) { 2106 throw new JOSEException("Couldn't encode x5t parameter: " + e.getMessage(), e); 2107 } catch (CertificateEncodingException e) { 2108 throw new JOSEException("Couldn't encode x5c parameter: " + e.getMessage(), e); 2109 } 2110 } 2111 2112 2113 /** 2114 * Loads a public / private RSA JWK from the specified JCA key store. 2115 * 2116 * <p><strong>Important:</strong> The X.509 certificate is not 2117 * validated! 2118 * 2119 * @param keyStore The key store. Must not be {@code null}. 2120 * @param alias The alias. Must not be {@code null}. 2121 * @param pin The pin to unlock the private key if any, empty or 2122 * {@code null} if not required. 2123 * 2124 * @return The public / private RSA key, {@code null} if no key with 2125 * the specified alias was found. 2126 * 2127 * @throws KeyStoreException On a key store exception. 2128 * @throws JOSEException If RSA key loading failed. 2129 */ 2130 public static RSAKey load(final KeyStore keyStore, 2131 final String alias, 2132 final char[] pin) 2133 throws KeyStoreException, JOSEException { 2134 2135 java.security.cert.Certificate cert = keyStore.getCertificate(alias); 2136 2137 if (cert == null || ! (cert instanceof X509Certificate)) { 2138 return null; 2139 } 2140 2141 X509Certificate x509Cert = (X509Certificate)cert; 2142 2143 if (! (x509Cert.getPublicKey() instanceof RSAPublicKey)) { 2144 throw new JOSEException("Couldn't load RSA JWK: The key algorithm is not RSA"); 2145 } 2146 2147 RSAKey rsaJWK = RSAKey.parse(x509Cert); 2148 2149 // Let kid=alias 2150 rsaJWK = new RSAKey.Builder(rsaJWK).keyID(alias).keyStore(keyStore).build(); 2151 2152 // Check for private counterpart 2153 Key key; 2154 try { 2155 key = keyStore.getKey(alias, pin); 2156 } catch (UnrecoverableKeyException | NoSuchAlgorithmException e) { 2157 throw new JOSEException("Couldn't retrieve private RSA key (bad pin?): " + e.getMessage(), e); 2158 } 2159 2160 if (key instanceof RSAPrivateKey) { 2161 // Simple file based key store 2162 return new RSAKey.Builder(rsaJWK) 2163 .privateKey((RSAPrivateKey)key) 2164 .build(); 2165 } else if (key instanceof PrivateKey && "RSA".equalsIgnoreCase(key.getAlgorithm())) { 2166 // PKCS#11 store 2167 return new RSAKey.Builder(rsaJWK) 2168 .privateKey((PrivateKey)key) 2169 .build(); 2170 } else { 2171 return rsaJWK; 2172 } 2173 } 2174}