001package com.nimbusds.jose.jwk; 002 003 004import java.net.URL; 005import java.math.BigInteger; 006import java.security.KeyFactory; 007import java.security.KeyPair; 008import java.security.NoSuchAlgorithmException; 009import java.security.interfaces.RSAMultiPrimePrivateCrtKey; 010import java.security.interfaces.RSAPrivateCrtKey; 011import java.security.interfaces.RSAPrivateKey; 012import java.security.interfaces.RSAPublicKey; 013import java.security.spec.InvalidKeySpecException; 014import java.security.spec.RSAMultiPrimePrivateCrtKeySpec; 015import java.security.spec.RSAOtherPrimeInfo; 016import java.security.spec.RSAPrivateCrtKeySpec; 017import java.security.spec.RSAPrivateKeySpec; 018import java.security.spec.RSAPublicKeySpec; 019import java.text.ParseException; 020import java.util.ArrayList; 021import java.util.Collections; 022import java.util.List; 023import java.util.Set; 024 025import net.jcip.annotations.Immutable; 026 027import net.minidev.json.JSONArray; 028import net.minidev.json.JSONObject; 029 030import com.nimbusds.jose.Algorithm; 031import com.nimbusds.jose.util.Base64; 032import com.nimbusds.jose.util.Base64URL; 033import com.nimbusds.jose.util.JSONObjectUtils; 034import com.nimbusds.jose.util.X509CertChainUtils; 035 036 037/** 038 * Public and private {@link KeyType#RSA RSA} JSON Web Key (JWK). This class is 039 * immutable. 040 * 041 * <p>Provides RSA JWK import from / export to the following standard Java 042 * interfaces and classes: 043 * 044 * <ul> 045 * <li>{@code java.security.interfaces.RSAPublicKey} 046 * <li>{@code java.security.interfaces.RSAPrivateKey} 047 * <ul> 048 * <li>{@code java.security.interfaces.RSAPrivateCrtKey} 049 * <li>{@code java.security.interfaces.RSAMultiPrimePrivateCrtKey} 050 * </ul> 051 * <li>{@code java.security.KeyPair} 052 * </ul> 053 * 054 * <p>Example JSON object representation of a public RSA JWK: 055 * 056 * <pre> 057 * { 058 * "kty" : "RSA", 059 * "n" : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 060 * 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs 061 * tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 062 * QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI 063 * SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb 064 * w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", 065 * "e" : "AQAB", 066 * "alg" : "RS256", 067 * "kid" : "2011-04-29" 068 * } 069 * </pre> 070 * 071 * <p>Example JSON object representation of a public and private RSA JWK (with 072 * both the first and the second private key representations): 073 * 074 * <pre> 075 * { 076 * "kty" : "RSA", 077 * "n" : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 078 * 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs 079 * tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 080 * QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI 081 * SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb 082 * w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", 083 * "e" : "AQAB", 084 * "d" : "X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9 085 * M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqij 086 * wp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d 087 * _cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBz 088 * nbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFz 089 * me1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q", 090 * "p" : "83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPV 091 * nwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqV 092 * WlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs", 093 * "q" : "3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyum 094 * qjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgx 095 * kIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk", 096 * "dp" : "G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oim 097 * YwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_Nmtu 098 * YZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0", 099 * "dq" : "s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUU 100 * vMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9 101 * GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk", 102 * "qi" : "GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzg 103 * UIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rx 104 * yR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU", 105 * "alg" : "RS256", 106 * "kid" : "2011-04-29" 107 * } 108 * </pre> 109 * 110 * <p>See RFC 3447. 111 * 112 * <p>See http://en.wikipedia.org/wiki/RSA_%28algorithm%29 113 * 114 * @author Vladimir Dzhuvinov 115 * @author Justin Richer 116 * @author Cedric Staub 117 * @version $version$ (2014-04-02) 118 */ 119@Immutable 120public final class RSAKey extends JWK { 121 122 123 /** 124 * Other Primes Info, represents the private {@code oth} parameter of a 125 * RSA JWK. This class is immutable. 126 */ 127 @Immutable 128 public static class OtherPrimesInfo { 129 130 131 /** 132 * The prime factor. 133 */ 134 private final Base64URL r; 135 136 137 /** 138 * The factor Chinese Remainder Theorem (CRT) exponent. 139 */ 140 private final Base64URL d; 141 142 143 /** 144 * The factor Chinese Remainder Theorem (CRT) coefficient. 145 */ 146 private final Base64URL t; 147 148 149 /** 150 * Creates a new JWK Other Primes Info with the specified 151 * parameters. 152 * 153 * @param r The prime factor. Must not be {@code null}. 154 * @param d The factor Chinese Remainder Theorem (CRT) 155 * exponent. Must not be {@code null}. 156 * @param t The factor Chinese Remainder Theorem (CRT) 157 * coefficient. Must not be {@code null}. 158 */ 159 public OtherPrimesInfo(final Base64URL r, final Base64URL d, final Base64URL t) { 160 161 if (r == null) { 162 163 throw new IllegalArgumentException("The prime factor must not be null"); 164 } 165 166 this.r = r; 167 168 if (d == null) { 169 170 throw new IllegalArgumentException("The factor CRT exponent must not be null"); 171 } 172 173 this.d = d; 174 175 if (t == null) { 176 177 throw new IllegalArgumentException("The factor CRT coefficient must not be null"); 178 } 179 180 this.t = t; 181 } 182 183 184 /** 185 * Creates a new JWK Other Primes Info from the specified 186 * {@code java.security.spec.RSAOtherPrimeInfo} instance. 187 * 188 * @param oth The RSA Other Primes Info instance. Must not be 189 * {@code null}. 190 */ 191 public OtherPrimesInfo(final RSAOtherPrimeInfo oth) { 192 193 r = Base64URL.encode(oth.getPrime()); 194 d = Base64URL.encode(oth.getExponent()); 195 t = Base64URL.encode(oth.getCrtCoefficient()); 196 } 197 198 199 /** 200 * Gets the prime factor ({@code r}). 201 * 202 * @return The prime factor. 203 */ 204 public Base64URL getPrimeFactor() { 205 206 return r; 207 } 208 209 210 /** 211 * Gets factor Chinese Remainder Theorem (CRT) exponent 212 * ({@code d}). 213 * 214 * @return The factor Chinese Remainder Theorem (CRT) exponent. 215 */ 216 public Base64URL getFactorCRTExponent() { 217 218 return d; 219 } 220 221 222 /** 223 * The factor Chinese Remainder Theorem (CRT) coefficient 224 * ({@code t}). 225 * 226 * @return The factor Chinese Remainder Theorem (CRT) 227 * coefficient. 228 */ 229 public Base64URL getFactorCRTCoefficient() { 230 231 return t; 232 } 233 234 235 /** 236 * Converts the specified array of 237 * {@code java.security.spec.RSAOtherPrimeInfo} instances to a 238 * list of JWK Other Prime Infos. 239 * 240 * @param othArray Array of RSA Other Primes Info instances. 241 * May be be {@code null}. 242 * 243 * @return The corresponding list of JWK Other Prime Infos, or 244 * empty list of the array was {@code null}. 245 */ 246 public static List<OtherPrimesInfo> toList(final RSAOtherPrimeInfo[] othArray) { 247 248 List<OtherPrimesInfo> list = new ArrayList<>(); 249 250 if (othArray == null) { 251 252 // Return empty list 253 return list; 254 } 255 256 for (RSAOtherPrimeInfo oth: othArray) { 257 258 list.add(new OtherPrimesInfo(oth)); 259 } 260 261 return list; 262 } 263 } 264 265 266 /** 267 * Builder for constructing RSA JWKs. 268 * 269 * <p>Example use: 270 * 271 * <pre> 272 * RSAKey key = new RSAKey.Builder(n, e). 273 * privateExponent(d). 274 * algorithm(JWSAlgorithm.RS512). 275 * keyID("456"). 276 * build(); 277 * </pre> 278 */ 279 public static class Builder { 280 281 282 // Public RSA params 283 284 /** 285 * The modulus value for the RSA key. 286 */ 287 private final Base64URL n; 288 289 290 /** 291 * The public exponent of the RSA key. 292 */ 293 private final Base64URL e; 294 295 296 // Private RSA params, 1st representation 297 298 /** 299 * The private exponent of the RSA key. 300 */ 301 private Base64URL d; 302 303 304 // Private RSA params, 2nd representation 305 306 /** 307 * The first prime factor of the private RSA key. 308 */ 309 private Base64URL p; 310 311 312 /** 313 * The second prime factor of the private RSA key. 314 */ 315 private Base64URL q; 316 317 318 /** 319 * The first factor Chinese Remainder Theorem exponent of the 320 * private RSA key. 321 */ 322 private Base64URL dp; 323 324 325 /** 326 * The second factor Chinese Remainder Theorem exponent of the 327 * private RSA key. 328 */ 329 private Base64URL dq; 330 331 332 /** 333 * The first Chinese Remainder Theorem coefficient of the private RSA 334 * key. 335 */ 336 private Base64URL qi; 337 338 339 /** 340 * The other primes information of the private RSA key, should 341 * they exist. When only two primes have been used (the normal 342 * case), this parameter MUST be omitted. When three or more 343 * primes have been used, the number of array elements MUST be 344 * the number of primes used minus two. 345 */ 346 private List<OtherPrimesInfo> oth; 347 348 349 /** 350 * The key use, optional. 351 */ 352 private KeyUse use; 353 354 355 /** 356 * The key operations, optional. 357 */ 358 private Set<KeyOperation> ops; 359 360 361 /** 362 * The intended JOSE algorithm for the key, optional. 363 */ 364 private Algorithm alg; 365 366 367 /** 368 * The key ID, optional. 369 */ 370 private String kid; 371 372 373 /** 374 * X.509 certificate URL, optional. 375 */ 376 private URL x5u; 377 378 379 /** 380 * X.509 certificate thumbprint, optional. 381 */ 382 private Base64URL x5t; 383 384 385 /** 386 * The X.509 certificate chain, optional. 387 */ 388 private List<Base64> x5c; 389 390 391 /** 392 * Creates a new RSA JWK builder. 393 * 394 * @param n The the modulus value for the public RSA key. It is 395 * represented as the Base64URL encoding of value's 396 * big endian representation. Must not be 397 * {@code null}. 398 * @param e The exponent value for the public RSA key. It is 399 * represented as the Base64URL encoding of value's 400 * big endian representation. Must not be 401 * {@code null}. 402 */ 403 public Builder(final Base64URL n, final Base64URL e) { 404 405 // Ensure the public params are defined 406 407 if (n == null) { 408 throw new IllegalArgumentException("The modulus value must not be null"); 409 } 410 411 this.n = n; 412 413 414 if (e == null) { 415 throw new IllegalArgumentException("The public exponent value must not be null"); 416 } 417 418 this.e = e; 419 } 420 421 422 /** 423 * Creates a new RSA JWK builder. 424 * 425 * @param pub The public RSA key to represent. Must not be 426 * {@code null}. 427 */ 428 public Builder(final RSAPublicKey pub) { 429 430 n = Base64URL.encode(pub.getModulus()); 431 e = Base64URL.encode(pub.getPublicExponent()); 432 } 433 434 435 /** 436 * Sets the private exponent ({@code d}) of the RSA key. 437 * 438 * @param d The private RSA key exponent. It is represented as 439 * the Base64URL encoding of the value's big endian 440 * representation. {@code null} if not specified (for 441 * a public key or a private key using the second 442 * representation only). 443 * 444 * @return This builder. 445 */ 446 public Builder privateExponent(final Base64URL d) { 447 448 this.d = d; 449 return this; 450 } 451 452 453 /** 454 * Sets the private RSA key, using the first representation. 455 * 456 * @param priv The private RSA key, used to obtain the private 457 * exponent ({@code d}). Must not be {@code null}. 458 * 459 * @return This builder. 460 */ 461 public Builder privateKey(final RSAPrivateKey priv) { 462 463 if (priv instanceof RSAPrivateCrtKey) { 464 return this.privateKey((RSAPrivateCrtKey) priv); 465 } else if (priv instanceof RSAMultiPrimePrivateCrtKey) { 466 return this.privateKey((RSAMultiPrimePrivateCrtKey) priv); 467 } else { 468 this.d = Base64URL.encode(priv.getPrivateExponent()); 469 return this; 470 } 471 } 472 473 474 /** 475 * Sets the first prime factor ({@code p}) of the private RSA 476 * key. 477 * 478 * @param p The RSA first prime factor. It is represented as 479 * the Base64URL encoding of the value's big endian 480 * representation. {@code null} if not specified (for 481 * a public key or a private key using the first 482 * representation only). 483 * 484 * @return This builder. 485 */ 486 public Builder firstPrimeFactor(final Base64URL p) { 487 488 this.p = p; 489 return this; 490 } 491 492 493 /** 494 * Sets the second prime factor ({@code q}) of the private RSA 495 * key. 496 * 497 * @param q The RSA second prime factor. It is represented as 498 * the Base64URL encoding of the value's big endian 499 * representation. {@code null} if not specified (for 500 * a public key or a private key using the first 501 * representation only). 502 * 503 * @return This builder. 504 */ 505 public Builder secondPrimeFactor(final Base64URL q) { 506 507 this.q = q; 508 return this; 509 } 510 511 512 /** 513 * Sets the first factor Chinese Remainder Theorem (CRT) 514 * exponent ({@code dp}) of the private RSA key. 515 * 516 * @param dp The RSA first factor CRT exponent. It is 517 * represented as the Base64URL encoding of the 518 * value's big endian representation. {@code null} 519 * if not specified (for a public key or a private 520 * key using the first representation only). 521 * 522 * @return This builder. 523 */ 524 public Builder firstFactorCRTExponent(final Base64URL dp) { 525 526 this.dp = dp; 527 return this; 528 } 529 530 531 /** 532 * Sets the second factor Chinese Remainder Theorem (CRT) 533 * exponent ({@code dq}) of the private RSA key. 534 * 535 * @param dq The RSA second factor CRT exponent. It is 536 * represented as the Base64URL encoding of the 537 * value's big endian representation. {@code null} if 538 * not specified (for a public key or a private key 539 * using the first representation only). 540 * 541 * @return This builder. 542 */ 543 public Builder secondFactorCRTExponent(final Base64URL dq) { 544 545 this.dq = dq; 546 return this; 547 } 548 549 550 /** 551 * Sets the first Chinese Remainder Theorem (CRT) coefficient 552 * ({@code qi})} of the private RSA key. 553 * 554 * @param qi The RSA first CRT coefficient. It is represented 555 * as the Base64URL encoding of the value's big 556 * endian representation. {@code null} if not 557 * specified (for a public key or a private key using 558 * the first representation only). 559 * 560 * @return This builder. 561 */ 562 public Builder firstCRTCoefficient(final Base64URL qi) { 563 564 this.qi = qi; 565 return this; 566 } 567 568 569 /** 570 * Sets the other primes information ({@code oth}) for the 571 * private RSA key, should they exist. 572 * 573 * @param oth The RSA other primes information, {@code null} or 574 * empty list if not specified. 575 * 576 * @return This builder. 577 */ 578 public Builder otherPrimes(final List<OtherPrimesInfo> oth) { 579 580 this.oth = oth; 581 return this; 582 } 583 584 585 /** 586 * Sets the private RSA key, using the second representation 587 * (see RFC 3447, section 3.2). 588 * 589 * @param priv The private RSA key, used to obtain the private 590 * exponent ({@code d}), the first prime factor 591 * ({@code p}), the second prime factor 592 * ({@code q}), the first factor CRT exponent 593 * ({@code dp}), the second factor CRT exponent 594 * ({@code dq}) and the first CRT coefficient 595 * ({@code qi}). Must not be {@code null}. 596 * 597 * @return This builder. 598 */ 599 public Builder privateKey(final RSAPrivateCrtKey priv) { 600 601 d = Base64URL.encode(priv.getPrivateExponent()); 602 p = Base64URL.encode(priv.getPrimeP()); 603 q = Base64URL.encode(priv.getPrimeQ()); 604 dp = Base64URL.encode(priv.getPrimeExponentP()); 605 dq = Base64URL.encode(priv.getPrimeExponentQ()); 606 qi = Base64URL.encode(priv.getCrtCoefficient()); 607 608 return this; 609 } 610 611 612 /** 613 * Sets the private RSA key, using the second representation, 614 * with optional other primes info (see RFC 3447, section 3.2). 615 * 616 * @param priv The private RSA key, used to obtain the private 617 * exponent ({@code d}), the first prime factor 618 * ({@code p}), the second prime factor 619 * ({@code q}), the first factor CRT exponent 620 * ({@code dp}), the second factor CRT exponent 621 * ({@code dq}), the first CRT coefficient 622 * ({@code qi}) and the other primes info 623 * ({@code oth}). Must not be {@code null}. 624 * 625 * @return This builder. 626 */ 627 public Builder privateKey(final RSAMultiPrimePrivateCrtKey priv) { 628 629 d = Base64URL.encode(priv.getPrivateExponent()); 630 p = Base64URL.encode(priv.getPrimeP()); 631 q = Base64URL.encode(priv.getPrimeQ()); 632 dp = Base64URL.encode(priv.getPrimeExponentP()); 633 dq = Base64URL.encode(priv.getPrimeExponentQ()); 634 qi = Base64URL.encode(priv.getCrtCoefficient()); 635 oth = OtherPrimesInfo.toList(priv.getOtherPrimeInfo()); 636 637 return this; 638 } 639 640 641 /** 642 * Sets the use ({@code use}) of the JWK. 643 * 644 * @param use The key use, {@code null} if not specified or if 645 * the key is intended for signing as well as 646 * encryption. 647 * 648 * @return This builder. 649 */ 650 public Builder keyUse(final KeyUse use) { 651 652 this.use = use; 653 return this; 654 } 655 656 657 /** 658 * Sets the operations ({@code key_ops}) of the JWK (for a 659 * non-public key). 660 * 661 * @param ops The key operations, {@code null} if not 662 * specified. 663 * 664 * @return This builder. 665 */ 666 public Builder keyOperations(final Set<KeyOperation> ops) { 667 668 this.ops = ops; 669 return this; 670 } 671 672 673 /** 674 * Sets the intended JOSE algorithm ({@code alg}) for the JWK. 675 * 676 * @param alg The intended JOSE algorithm, {@code null} if not 677 * specified. 678 * 679 * @return This builder. 680 */ 681 public Builder algorithm(final Algorithm alg) { 682 683 this.alg = alg; 684 return this; 685 } 686 687 /** 688 * Sets the ID ({@code kid}) of the JWK. The key ID can be used 689 * to match a specific key. This can be used, for instance, to 690 * choose a key within a {@link JWKSet} during key rollover. 691 * The key ID may also correspond to a JWS/JWE {@code kid} 692 * header parameter value. 693 * 694 * @param kid The key ID, {@code null} if not specified. 695 * 696 * @return This builder. 697 */ 698 public Builder keyID(final String kid) { 699 700 this.kid = kid; 701 return this; 702 } 703 704 705 /** 706 * Sets the X.509 certificate URL ({@code x5u}) of the JWK. 707 * 708 * @param x5u The X.509 certificate URL, {@code null} if not 709 * specified. 710 * 711 * @return This builder. 712 */ 713 public Builder x509CertURL(final URL x5u) { 714 715 this.x5u = x5u; 716 return this; 717 } 718 719 720 /** 721 * Sets the X.509 certificate thumbprint ({@code x5t}) of the 722 * JWK. 723 * 724 * @param x5t The X.509 certificate thumbprint, {@code null} if 725 * not specified. 726 * 727 * @return This builder. 728 */ 729 public Builder x509CertThumbprint(final Base64URL x5t) { 730 731 this.x5t = x5t; 732 return this; 733 } 734 735 /** 736 * Sets the X.509 certificate chain ({@code x5c}) of the JWK. 737 * 738 * @param x5c The X.509 certificate chain as a unmodifiable 739 * list, {@code null} if not specified. 740 * 741 * @return This builder. 742 */ 743 public Builder x509CertChain(final List<Base64> x5c) { 744 745 this.x5c = x5c; 746 return this; 747 } 748 749 /** 750 * Builds a new RSA JWK. 751 * 752 * @return The RSA JWK. 753 * 754 * @throws IllegalStateException If the JWK parameters were 755 * inconsistently specified. 756 */ 757 public RSAKey build() { 758 759 try { 760 // The full constructor 761 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, 762 use, ops, alg, kid, x5u, x5t, x5c); 763 764 } catch (IllegalArgumentException e) { 765 766 throw new IllegalStateException(e.getMessage(), e); 767 } 768 } 769 } 770 771 772 // Public RSA params 773 774 /** 775 * The modulus value of the RSA key. 776 */ 777 private final Base64URL n; 778 779 780 /** 781 * The public exponent of the RSA key. 782 */ 783 private final Base64URL e; 784 785 786 // Private RSA params, 1st representation 787 788 /** 789 * The private exponent of the RSA key. 790 */ 791 private final Base64URL d; 792 793 794 // Private RSA params, 2nd representation 795 796 /** 797 * The first prime factor of the private RSA key. 798 */ 799 private final Base64URL p; 800 801 802 /** 803 * The second prime factor of the private RSA key. 804 */ 805 private final Base64URL q; 806 807 808 /** 809 * The first factor Chinese Remainder Theorem exponent of the private 810 * RSA key. 811 */ 812 private final Base64URL dp; 813 814 815 /** 816 * The second factor Chinese Remainder Theorem exponent of the private 817 * RSA key. 818 */ 819 private final Base64URL dq; 820 821 822 /** 823 * The first Chinese Remainder Theorem coefficient of the private RSA 824 * key. 825 */ 826 private final Base64URL qi; 827 828 829 /** 830 * The other primes information of the private RSA key, should they 831 * exist. When only two primes have been used (the normal case), this 832 * parameter MUST be omitted. When three or more primes have been used, 833 * the number of array elements MUST be the number of primes used minus 834 * two. 835 */ 836 private final List<OtherPrimesInfo> oth; 837 838 839 /** 840 * Creates a new public RSA JSON Web Key (JWK) with the specified 841 * parameters. 842 * 843 * @param n The the modulus value for the public RSA key. It is 844 * represented as the Base64URL encoding of value's big 845 * endian representation. Must not be {@code null}. 846 * @param e The exponent value for the public RSA key. It is 847 * represented as the Base64URL encoding of value's big 848 * endian representation. Must not be {@code null}. 849 * @param use The key use, {@code null} if not specified or if the key 850 * is intended for signing as well as encryption. 851 * @param ops The key operations, {@code null} if not specified. 852 * @param alg The intended JOSE algorithm for the key, {@code null} if 853 * not specified. 854 * @param kid The key ID. {@code null} if not specified. 855 * @param x5u The X.509 certificate URL, {@code null} if not specified. 856 * @param x5t The X.509 certificate thumbprint, {@code null} if not 857 * specified. 858 * @param x5c The X.509 certificate chain, {@code null} if not 859 * specified. 860 */ 861 public RSAKey(final Base64URL n, final Base64URL e, 862 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 863 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 864 865 // Call the full constructor, all private key parameters are null 866 this(n, e, null, null, null, null, null, null, null, use, ops, alg, kid, 867 x5u, x5t, x5c); 868 } 869 870 871 /** 872 * Creates a new public / private RSA JSON Web Key (JWK) with the 873 * specified parameters. The private RSA key is specified by its first 874 * representation (see RFC 3447, section 3.2). 875 * 876 * @param n The the modulus value for the public RSA key. It is 877 * represented as the Base64URL encoding of value's big 878 * endian representation. Must not be {@code null}. 879 * @param e The exponent value for the public RSA key. It is 880 * represented as the Base64URL encoding of value's big 881 * endian representation. Must not be {@code null}. 882 * @param d The private exponent. It is represented as the Base64URL 883 * encoding of the value's big endian representation. Must 884 * not be {@code null}. 885 * @param use The key use, {@code null} if not specified or if the key 886 * is intended for signing as well as encryption. 887 * @param ops The key operations, {@code null} if not specified. 888 * @param alg The intended JOSE algorithm for the key, {@code null} if 889 * not specified. 890 * @param kid The key ID. {@code null} if not specified. 891 * @param x5u The X.509 certificate URL, {@code null} if not specified. 892 * @param x5t The X.509 certificate thumbprint, {@code null} if not 893 * specified. 894 * @param x5c The X.509 certificate chain, {@code null} if not 895 * specified. 896 */ 897 public RSAKey(final Base64URL n, final Base64URL e, final Base64URL d, 898 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 899 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 900 901 // Call the full constructor, the second private representation 902 // parameters are all null 903 this(n, e, d, null, null, null, null, null, null, use, ops, alg, kid, 904 x5u, x5t, x5c); 905 906 if (d == null) { 907 throw new IllegalArgumentException("The private exponent must not be null"); 908 } 909 } 910 911 912 /** 913 * Creates a new public / private RSA JSON Web Key (JWK) with the 914 * specified parameters. The private RSA key is specified by its 915 * second representation (see RFC 3447, section 3.2). 916 * 917 * @param n The the modulus value for the public RSA key. It is 918 * represented as the Base64URL encoding of value's big 919 * endian representation. Must not be {@code null}. 920 * @param e The exponent value for the public RSA key. It is 921 * represented as the Base64URL encoding of value's big 922 * endian representation. Must not be {@code null}. 923 * @param p The first prime factor. It is represented as the 924 * Base64URL encoding of the value's big endian 925 * representation. Must not be {@code null}. 926 * @param q The second prime factor. It is represented as the 927 * Base64URL encoding of the value's big endian 928 * representation. Must not be {@code null}. 929 * @param dp The first factor Chinese Remainder Theorem exponent. It 930 * is represented as the Base64URL encoding of the value's 931 * big endian representation. Must not be {@code null}. 932 * @param dq The second factor Chinese Remainder Theorem exponent. It 933 * is represented as the Base64URL encoding of the value's 934 * big endian representation. Must not be {@code null}. 935 * @param qi The first Chinese Remainder Theorem coefficient. It is 936 * represented as the Base64URL encoding of the value's big 937 * endian representation. Must not be {@code null}. 938 * @param oth The other primes information, should they exist, 939 * {@code null} or an empty list if not specified. 940 * @param use The key use, {@code null} if not specified or if the key 941 * is intended for signing as well as encryption. 942 * @param ops The key operations, {@code null} if not specified. 943 * @param alg The intended JOSE algorithm for the key, {@code null} if 944 * not specified. 945 * @param kid The key ID. {@code null} if not specified. 946 * @param x5u The X.509 certificate URL, {@code null} if not specified. 947 * @param x5t The X.509 certificate thumbprint, {@code null} if not 948 * specified. 949 * @param x5c The X.509 certificate chain, {@code null} if not 950 * specified. 951 */ 952 public RSAKey(final Base64URL n, final Base64URL e, 953 final Base64URL p, final Base64URL q, 954 final Base64URL dp, final Base64URL dq, final Base64URL qi, 955 final List<OtherPrimesInfo> oth, 956 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 957 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 958 959 // Call the full constructor, the first private representation 960 // d param is null 961 this(n, e, null, p, q, dp, dq, qi, oth, use, ops, alg, kid, 962 x5u, x5t, x5c); 963 964 if (p == null) { 965 throw new IllegalArgumentException("The first prime factor must not be null"); 966 } 967 968 if (q == null) { 969 throw new IllegalArgumentException("The second prime factor must not be null"); 970 } 971 972 if (dp == null) { 973 throw new IllegalArgumentException("The first factor CRT exponent must not be null"); 974 } 975 976 if (dq == null) { 977 throw new IllegalArgumentException("The second factor CRT exponent must not be null"); 978 } 979 980 if (qi == null) { 981 throw new IllegalArgumentException("The first CRT coefficient must not be null"); 982 } 983 } 984 985 986 /** 987 * Creates a new public / private RSA JSON Web Key (JWK) with the 988 * specified parameters. The private RSA key is specified by both its 989 * first and second representations (see RFC 3447, section 3.2). 990 * 991 * <p>A valid first private RSA key representation must specify the 992 * {@code d} parameter. 993 * 994 * <p>A valid second private RSA key representation must specify all 995 * required Chinese Remained Theorem (CRT) parameters - {@code p}, 996 * {@code q}, {@code dp}, {@code dq} and {@code qi}, else an 997 * {@link java.lang.IllegalArgumentException} will be thrown. 998 * 999 * @param n The the modulus value for the public RSA key. It is 1000 * represented as the Base64URL encoding of value's big 1001 * endian representation. Must not be {@code null}. 1002 * @param e The exponent value for the public RSA key. It is 1003 * represented as the Base64URL encoding of value's big 1004 * endian representation. Must not be {@code null}. 1005 * @param d The private exponent. It is represented as the Base64URL 1006 * encoding of the value's big endian representation. May 1007 * be {@code null}. 1008 * @param p The first prime factor. It is represented as the 1009 * Base64URL encoding of the value's big endian 1010 * representation. May be {@code null}. 1011 * @param q The second prime factor. It is represented as the 1012 * Base64URL encoding of the value's big endian 1013 * representation. May be {@code null}. 1014 * @param dp The first factor Chinese Remainder Theorem exponent. It 1015 * is represented as the Base64URL encoding of the value's 1016 * big endian representation. May be {@code null}. 1017 * @param dq The second factor Chinese Remainder Theorem exponent. It 1018 * is represented as the Base64URL encoding of the value's 1019 * big endian representation. May be {@code null}. 1020 * @param qi The first Chinese Remainder Theorem coefficient. It is 1021 * represented as the Base64URL encoding of the value's big 1022 * endian representation. May be {@code null}. 1023 * @param oth The other primes information, should they exist, 1024 * {@code null} or an empty list if not specified. 1025 * @param use The key use, {@code null} if not specified or if the key 1026 * is intended for signing as well as encryption. 1027 * @param ops The key operations, {@code null} if not specified. 1028 * @param alg The intended JOSE algorithm for the key, {@code null} if 1029 * not specified. 1030 * @param kid The key ID. {@code null} if not specified. 1031 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1032 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1033 * specified. 1034 * @param x5c The X.509 certificate chain, {@code null} if not 1035 * specified. 1036 */ 1037 public RSAKey(final Base64URL n, final Base64URL e, 1038 final Base64URL d, 1039 final Base64URL p, final Base64URL q, 1040 final Base64URL dp, final Base64URL dq, final Base64URL qi, 1041 final List<OtherPrimesInfo> oth, 1042 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1043 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 1044 1045 super(KeyType.RSA, use, ops, alg, kid, x5u, x5t, x5c); 1046 1047 1048 // Ensure the public params are defined 1049 1050 if (n == null) { 1051 throw new IllegalArgumentException("The modulus value must not be null"); 1052 } 1053 1054 this.n = n; 1055 1056 1057 if (e == null) { 1058 throw new IllegalArgumentException("The public exponent value must not be null"); 1059 } 1060 1061 this.e = e; 1062 1063 1064 // Private params, 1st representation 1065 1066 this.d = d; 1067 1068 1069 // Private params, 2nd representation, check for consistency 1070 1071 if (p != null && q != null && dp != null && dq != null && qi != null) { 1072 1073 // CRT params fully specified 1074 this.p = p; 1075 this.q = q; 1076 this.dp = dp; 1077 this.dq = dq; 1078 this.qi = qi; 1079 1080 // Other RSA primes info optional, default to empty list 1081 if (oth != null) { 1082 this.oth = Collections.unmodifiableList(oth); 1083 } else { 1084 this.oth = Collections.emptyList(); 1085 } 1086 1087 } else if (p == null && q == null && dp == null && dq == null && qi == null && oth == null) { 1088 1089 // No CRT params 1090 this.p = null; 1091 this.q = null; 1092 this.dp = null; 1093 this.dq = null; 1094 this.qi = null; 1095 1096 this.oth = Collections.emptyList(); 1097 1098 } else { 1099 1100 if (p == null) { 1101 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first prime factor must not be null"); 1102 } else if (q == null) { 1103 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second prime factor must not be null"); 1104 } else if (dp == null) { 1105 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first factor CRT exponent must not be null"); 1106 } else if (dq == null) { 1107 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second factor CRT exponent must not be null"); 1108 } else { // qi == null 1109 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first CRT coefficient must not be null"); 1110 } 1111 } 1112 } 1113 1114 1115 /** 1116 * Creates a new public RSA JSON Web Key (JWK) with the specified 1117 * parameters. 1118 * 1119 * @param pub The public RSA key to represent. Must not be 1120 * {@code null}. 1121 * @param use The key use, {@code null} if not specified or if the key 1122 * is intended for signing as well as encryption. 1123 * @param ops The key operations, {@code null} if not specified. 1124 * @param alg The intended JOSE algorithm for the key, {@code null} if 1125 * not specified. 1126 * @param kid The key ID. {@code null} if not specified. 1127 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1128 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1129 * specified. 1130 * @param x5c The X.509 certificate chain, {@code null} if not 1131 * specified. 1132 */ 1133 public RSAKey(final RSAPublicKey pub, 1134 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1135 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 1136 1137 this(Base64URL.encode(pub.getModulus()), 1138 Base64URL.encode(pub.getPublicExponent()), 1139 use, ops, alg, kid, 1140 x5u, x5t, x5c); 1141 } 1142 1143 1144 /** 1145 * Creates a new public / private RSA JSON Web Key (JWK) with the 1146 * specified parameters. The private RSA key is specified by its first 1147 * representation (see RFC 3447, section 3.2). 1148 * 1149 * @param pub The public RSA key to represent. Must not be 1150 * {@code null}. 1151 * @param priv The private RSA key to represent. Must not be 1152 * {@code null}. 1153 * @param use The key use, {@code null} if not specified or if the key 1154 * is intended for signing as well as encryption. 1155 * @param ops The key operations, {@code null} if not specified. 1156 * @param alg The intended JOSE algorithm for the key, {@code null} if 1157 * not specified. 1158 * @param kid The key ID. {@code null} if not specified. 1159 * @param x5u The X.509 certificate URL, {@code null} if not 1160 * specified. 1161 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1162 * specified. 1163 * @param x5c The X.509 certificate chain, {@code null} if not 1164 * specified. 1165 */ 1166 public RSAKey(final RSAPublicKey pub, final RSAPrivateKey priv, 1167 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1168 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 1169 1170 this(Base64URL.encode(pub.getModulus()), 1171 Base64URL.encode(pub.getPublicExponent()), 1172 Base64URL.encode(priv.getPrivateExponent()), 1173 use, ops, alg, kid, 1174 x5u, x5t, x5c); 1175 } 1176 1177 1178 /** 1179 * Creates a new public / private RSA JSON Web Key (JWK) with the 1180 * specified parameters. The private RSA key is specified by its second 1181 * representation (see RFC 3447, section 3.2). 1182 * 1183 * @param pub The public RSA key to represent. Must not be 1184 * {@code null}. 1185 * @param priv The private RSA key to represent. Must not be 1186 * {@code null}. 1187 * @param use The key use, {@code null} if not specified or if the key 1188 * is intended for signing as well as encryption. 1189 * @param ops The key operations, {@code null} if not specified. 1190 * @param alg The intended JOSE algorithm for the key, {@code null} if 1191 * not specified. 1192 * @param kid The key ID. {@code null} if not specified. 1193 * @param x5u The X.509 certificate URL, {@code null} if not 1194 * specified. 1195 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1196 * specified. 1197 * @param x5c The X.509 certificate chain, {@code null} if not 1198 * specified. 1199 */ 1200 public RSAKey(final RSAPublicKey pub, final RSAPrivateCrtKey priv, 1201 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1202 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 1203 1204 this(Base64URL.encode(pub.getModulus()), 1205 Base64URL.encode(pub.getPublicExponent()), 1206 Base64URL.encode(priv.getPrivateExponent()), 1207 Base64URL.encode(priv.getPrimeP()), 1208 Base64URL.encode(priv.getPrimeQ()), 1209 Base64URL.encode(priv.getPrimeExponentP()), 1210 Base64URL.encode(priv.getPrimeExponentQ()), 1211 Base64URL.encode(priv.getCrtCoefficient()), 1212 null, 1213 use, ops, alg, kid, 1214 x5u, x5t, x5c); 1215 } 1216 1217 1218 /** 1219 * Creates a new public / private RSA JSON Web Key (JWK) with the 1220 * specified parameters. The private RSA key is specified by its second 1221 * representation, with optional other primes info (see RFC 3447, 1222 * section 3.2). 1223 * 1224 * @param pub The public RSA key to represent. Must not be 1225 * {@code null}. 1226 * @param priv The private RSA key to represent. Must not be 1227 * {@code null}. 1228 * @param use The key use, {@code null} if not specified or if the key 1229 * is intended for signing as well as encryption. 1230 * @param ops The key operations, {@code null} if not specified. 1231 * @param alg The intended JOSE algorithm for the key, {@code null} if 1232 * not specified. 1233 * @param kid The key ID. {@code null} if not specified. 1234 * @param x5u The X.509 certificate URL, {@code null} if not 1235 * specified. 1236 * @param x5t The X.509 certificate thumbprint, {@code null} if not 1237 * specified. 1238 * @param x5c The X.509 certificate chain, {@code null} if not 1239 * specified. 1240 */ 1241 public RSAKey(final RSAPublicKey pub, final RSAMultiPrimePrivateCrtKey priv, 1242 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1243 final URL x5u, final Base64URL x5t, final List<Base64> x5c) { 1244 1245 this(Base64URL.encode(pub.getModulus()), 1246 Base64URL.encode(pub.getPublicExponent()), 1247 Base64URL.encode(priv.getPrivateExponent()), 1248 Base64URL.encode(priv.getPrimeP()), 1249 Base64URL.encode(priv.getPrimeQ()), 1250 Base64URL.encode(priv.getPrimeExponentP()), 1251 Base64URL.encode(priv.getPrimeExponentQ()), 1252 Base64URL.encode(priv.getCrtCoefficient()), 1253 OtherPrimesInfo.toList(priv.getOtherPrimeInfo()), 1254 use, ops, alg, kid, 1255 x5u, x5t, x5c); 1256 } 1257 1258 1259 /** 1260 * Gets the modulus value ({@code n}) of the RSA key. 1261 * 1262 * @return The RSA key modulus. It is represented as the Base64URL 1263 * encoding of the value's big endian representation. 1264 */ 1265 public Base64URL getModulus() { 1266 1267 return n; 1268 } 1269 1270 1271 /** 1272 * Gets the public exponent ({@code e}) of the RSA key. 1273 * 1274 * @return The public RSA key exponent. It is represented as the 1275 * Base64URL encoding of the value's big endian representation. 1276 */ 1277 public Base64URL getPublicExponent() { 1278 1279 return e; 1280 } 1281 1282 1283 /** 1284 * Gets the private exponent ({@code d}) of the RSA key. 1285 * 1286 * @return The private RSA key exponent. It is represented as the 1287 * Base64URL encoding of the value's big endian representation. 1288 * {@code null} if not specified (for a public key or a private 1289 * key using the second representation only). 1290 */ 1291 public Base64URL getPrivateExponent() { 1292 1293 return d; 1294 } 1295 1296 1297 /** 1298 * Gets the first prime factor ({@code p}) of the private RSA key. 1299 * 1300 * @return The RSA first prime factor. It is represented as the 1301 * Base64URL encoding of the value's big endian representation. 1302 * {@code null} if not specified (for a public key or a private 1303 * key using the first representation only). 1304 */ 1305 public Base64URL getFirstPrimeFactor() { 1306 1307 return p; 1308 } 1309 1310 1311 /** 1312 * Gets the second prime factor ({@code q}) of the private RSA key. 1313 * 1314 * @return The RSA second prime factor. It is represented as the 1315 * Base64URL encoding of the value's big endian representation. 1316 * {@code null} if not specified (for a public key or a private 1317 * key using the first representation only). 1318 */ 1319 public Base64URL getSecondPrimeFactor() { 1320 1321 return q; 1322 } 1323 1324 1325 /** 1326 * Gets the first factor Chinese Remainder Theorem (CRT) exponent 1327 * ({@code dp}) of the private RSA key. 1328 * 1329 * @return The RSA first factor CRT exponent. It is represented as the 1330 * Base64URL encoding of the value's big endian representation. 1331 * {@code null} if not specified (for a public key or a private 1332 * key using the first representation only). 1333 */ 1334 public Base64URL getFirstFactorCRTExponent() { 1335 1336 return dp; 1337 } 1338 1339 1340 /** 1341 * Gets the second factor Chinese Remainder Theorem (CRT) exponent 1342 * ({@code dq}) of the private RSA key. 1343 * 1344 * @return The RSA second factor CRT exponent. It is represented as the 1345 * Base64URL encoding of the value's big endian representation. 1346 * {@code null} if not specified (for a public key or a private 1347 * key using the first representation only). 1348 */ 1349 public Base64URL getSecondFactorCRTExponent() { 1350 1351 return dq; 1352 } 1353 1354 1355 /** 1356 * Gets the first Chinese Remainder Theorem (CRT) coefficient 1357 * ({@code qi})} of the private RSA key. 1358 * 1359 * @return The RSA first CRT coefficient. It is represented as the 1360 * Base64URL encoding of the value's big endian representation. 1361 * {@code null} if not specified (for a public key or a private 1362 * key using the first representation only). 1363 */ 1364 public Base64URL getFirstCRTCoefficient() { 1365 1366 return qi; 1367 } 1368 1369 1370 /** 1371 * Gets the other primes information ({@code oth}) for the private RSA 1372 * key, should they exist. 1373 * 1374 * @return The RSA other primes information, {@code null} or empty list 1375 * if not specified. 1376 */ 1377 public List<OtherPrimesInfo> getOtherPrimes() { 1378 1379 return oth; 1380 } 1381 1382 1383 /** 1384 * Returns a standard {@code java.security.interfaces.RSAPublicKey} 1385 * representation of this RSA JWK. 1386 * 1387 * @return The public RSA key. 1388 * 1389 * @throws NoSuchAlgorithmException If RSA is not supported by the 1390 * underlying Java Cryptography (JCA) 1391 * provider. 1392 * @throws InvalidKeySpecException If the JWK key parameters are 1393 * invalid for a public RSA key. 1394 */ 1395 public RSAPublicKey toRSAPublicKey() 1396 throws NoSuchAlgorithmException, InvalidKeySpecException { 1397 1398 BigInteger modulus = n.decodeToBigInteger(); 1399 BigInteger exponent = e.decodeToBigInteger(); 1400 1401 RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent); 1402 KeyFactory factory = KeyFactory.getInstance("RSA"); 1403 1404 return (RSAPublicKey)factory.generatePublic(spec); 1405 } 1406 1407 1408 /** 1409 * Returns a standard {@code java.security.interfaces.RSAPrivateKey} 1410 * representation of this RSA JWK. 1411 * 1412 * @return The private RSA key, {@code null} if not specified by this 1413 * JWK. 1414 * 1415 * @throws NoSuchAlgorithmException If RSA is not supported by the 1416 * underlying Java Cryptography (JCA) 1417 * provider. 1418 * @throws InvalidKeySpecException If the JWK key parameters are 1419 * invalid for a private RSA key. 1420 */ 1421 public RSAPrivateKey toRSAPrivateKey() 1422 throws NoSuchAlgorithmException, InvalidKeySpecException { 1423 1424 if (d == null) { 1425 // no private key 1426 return null; 1427 } 1428 1429 BigInteger modulus = n.decodeToBigInteger(); 1430 BigInteger privateExponent = d.decodeToBigInteger(); 1431 1432 RSAPrivateKeySpec spec; 1433 1434 if (p == null) { 1435 // Use 1st representation 1436 spec = new RSAPrivateKeySpec(modulus, privateExponent); 1437 1438 } else { 1439 // Use 2nd (CRT) representation 1440 BigInteger publicExponent = e.decodeToBigInteger(); 1441 BigInteger primeP = p.decodeToBigInteger(); 1442 BigInteger primeQ = q.decodeToBigInteger(); 1443 BigInteger primeExponentP = dp.decodeToBigInteger(); 1444 BigInteger primeExponentQ = dq.decodeToBigInteger(); 1445 BigInteger crtCoefficient = qi.decodeToBigInteger(); 1446 1447 if (oth != null && ! oth.isEmpty()) { 1448 // Construct other info spec 1449 RSAOtherPrimeInfo[] otherInfo = new RSAOtherPrimeInfo[oth.size()]; 1450 1451 for (int i=0; i < oth.size(); i++) { 1452 1453 OtherPrimesInfo opi = oth.get(i); 1454 1455 BigInteger otherPrime = opi.getPrimeFactor().decodeToBigInteger(); 1456 BigInteger otherPrimeExponent = opi.getFactorCRTExponent().decodeToBigInteger(); 1457 BigInteger otherCrtCoefficient = opi.getFactorCRTCoefficient().decodeToBigInteger(); 1458 1459 otherInfo[i] = new RSAOtherPrimeInfo(otherPrime, 1460 otherPrimeExponent, 1461 otherCrtCoefficient); 1462 } 1463 1464 spec = new RSAMultiPrimePrivateCrtKeySpec(modulus, 1465 publicExponent, 1466 privateExponent, 1467 primeP, 1468 primeQ, 1469 primeExponentP, 1470 primeExponentQ, 1471 crtCoefficient, 1472 otherInfo); 1473 } else { 1474 // Construct spec with no other info 1475 spec = new RSAPrivateCrtKeySpec(modulus, 1476 publicExponent, 1477 privateExponent, 1478 primeP, 1479 primeQ, 1480 primeExponentP, 1481 primeExponentQ, 1482 crtCoefficient); 1483 } 1484 } 1485 1486 KeyFactory factory = KeyFactory.getInstance("RSA"); 1487 1488 return (RSAPrivateKey)factory.generatePrivate(spec); 1489 } 1490 1491 1492 /** 1493 * Returns a standard {@code java.security.KeyPair} representation of 1494 * this RSA JWK. 1495 * 1496 * @return The RSA key pair. The private RSA key will be {@code null} 1497 * if not specified. 1498 * 1499 * @throws NoSuchAlgorithmException If RSA is not supported by the 1500 * underlying Java Cryptography (JCA) 1501 * provider. 1502 * @throws InvalidKeySpecException If the JWK key parameters are 1503 * invalid for a public and / or 1504 * private RSA key. 1505 */ 1506 public KeyPair toKeyPair() 1507 throws NoSuchAlgorithmException, InvalidKeySpecException { 1508 1509 return new KeyPair(toRSAPublicKey(), toRSAPrivateKey()); 1510 } 1511 1512 1513 @Override 1514 public boolean isPrivate() { 1515 1516 // Check if 1st or 2nd form params are specified 1517 return d != null || p != null; 1518 } 1519 1520 1521 /** 1522 * Returns a copy of this RSA JWK with any private values removed. 1523 * 1524 * @return The copied public RSA JWK. 1525 */ 1526 @Override 1527 public RSAKey toPublicJWK() { 1528 1529 return new RSAKey(getModulus(), getPublicExponent(), 1530 getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(), 1531 getX509CertURL(), getX509CertThumbprint(), getX509CertChain()); 1532 } 1533 1534 1535 @Override 1536 public JSONObject toJSONObject() { 1537 1538 JSONObject o = super.toJSONObject(); 1539 1540 // Append public RSA key specific attributes 1541 o.put("n", n.toString()); 1542 o.put("e", e.toString()); 1543 if (d != null) { 1544 o.put("d", d.toString()); 1545 } 1546 if (p != null) { 1547 o.put("p", p.toString()); 1548 } 1549 if (q != null) { 1550 o.put("q", q.toString()); 1551 } 1552 if (dp != null) { 1553 o.put("dp", dp.toString()); 1554 } 1555 if (dq != null) { 1556 o.put("dq", dq.toString()); 1557 } 1558 if (qi != null) { 1559 o.put("qi", qi.toString()); 1560 } 1561 if (oth != null && !oth.isEmpty()) { 1562 1563 JSONArray a = new JSONArray(); 1564 1565 for (OtherPrimesInfo other : oth) { 1566 1567 JSONObject oo = new JSONObject(); 1568 oo.put("r", other.r.toString()); 1569 oo.put("d", other.d.toString()); 1570 oo.put("t", other.t.toString()); 1571 1572 a.add(oo); 1573 } 1574 1575 o.put("oth", a); 1576 } 1577 1578 return o; 1579 } 1580 1581 1582 /** 1583 * Parses a public / private RSA Curve JWK from the specified JSON 1584 * object string representation. 1585 * 1586 * @param s The JSON object string to parse. Must not be {@code null}. 1587 * 1588 * @return The public / private RSA JWK. 1589 * 1590 * @throws ParseException If the string couldn't be parsed to an RSA 1591 * JWK. 1592 */ 1593 public static RSAKey parse(final String s) 1594 throws ParseException { 1595 1596 return parse(JSONObjectUtils.parseJSONObject(s)); 1597 } 1598 1599 1600 /** 1601 * Parses a public / private RSA JWK from the specified JSON object 1602 * representation. 1603 * 1604 * @param jsonObject The JSON object to parse. Must not be 1605 * @code null}. 1606 * 1607 * @return The public / private RSA Key. 1608 * 1609 * @throws ParseException If the JSON object couldn't be parsed to an 1610 * RSA JWK. 1611 */ 1612 public static RSAKey parse(final JSONObject jsonObject) 1613 throws ParseException { 1614 1615 // Parse the mandatory public key parameters first 1616 Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n")); 1617 Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e")); 1618 1619 // Check key type 1620 KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty")); 1621 if (kty != KeyType.RSA) { 1622 throw new ParseException("The key type \"kty\" must be RSA", 0); 1623 } 1624 1625 // Parse the optional private key parameters 1626 1627 // 1st private representation 1628 Base64URL d = null; 1629 if (jsonObject.containsKey("d")) { 1630 d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d")); 1631 } 1632 1633 // 2nd private (CRT) representation 1634 Base64URL p = null; 1635 if (jsonObject.containsKey("p")) { 1636 p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p")); 1637 } 1638 Base64URL q = null; 1639 if (jsonObject.containsKey("q")) { 1640 q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q")); 1641 } 1642 Base64URL dp = null; 1643 if (jsonObject.containsKey("dp")) { 1644 dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp")); 1645 } 1646 Base64URL dq= null; 1647 if (jsonObject.containsKey("dq")) { 1648 dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq")); 1649 } 1650 Base64URL qi = null; 1651 if (jsonObject.containsKey("qi")) { 1652 qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi")); 1653 } 1654 1655 List<OtherPrimesInfo> oth = null; 1656 if (jsonObject.containsKey("oth")) { 1657 1658 JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth"); 1659 oth = new ArrayList<>(arr.size()); 1660 1661 for (Object o : arr) { 1662 1663 if (o instanceof JSONObject) { 1664 JSONObject otherJson = (JSONObject)o; 1665 1666 Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r")); 1667 Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq")); 1668 Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t")); 1669 1670 OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t); 1671 oth.add(prime); 1672 } 1673 } 1674 } 1675 1676 // Get optional key use 1677 KeyUse use = null; 1678 1679 if (jsonObject.containsKey("use")) { 1680 use = KeyUse.parse(JSONObjectUtils.getString(jsonObject, "use")); 1681 } 1682 1683 // Get optional key operations 1684 Set<KeyOperation> ops = null; 1685 1686 if (jsonObject.containsKey("key_ops")) { 1687 ops = KeyOperation.parse(JSONObjectUtils.getStringList(jsonObject, "key_ops")); 1688 } 1689 1690 // Get optional intended algorithm 1691 Algorithm alg = null; 1692 1693 if (jsonObject.containsKey("alg")) { 1694 alg = new Algorithm(JSONObjectUtils.getString(jsonObject, "alg")); 1695 } 1696 1697 // Get optional key ID 1698 String kid = null; 1699 1700 if (jsonObject.containsKey("kid")) { 1701 kid = JSONObjectUtils.getString(jsonObject, "kid"); 1702 } 1703 1704 // Get optional X.509 cert URL 1705 URL x5u = null; 1706 1707 if (jsonObject.containsKey("x5u")) { 1708 x5u = JSONObjectUtils.getURL(jsonObject, "x5u"); 1709 } 1710 1711 // Get optional X.509 cert thumbprint 1712 Base64URL x5t = null; 1713 1714 if (jsonObject.containsKey("x5t")) { 1715 x5t = new Base64URL(JSONObjectUtils.getString(jsonObject, "x5t")); 1716 } 1717 1718 // Get optional X.509 cert chain 1719 List<Base64> x5c = null; 1720 1721 if (jsonObject.containsKey("x5c")) { 1722 x5c = X509CertChainUtils.parseX509CertChain(JSONObjectUtils.getJSONArray(jsonObject, "x5c")); 1723 } 1724 1725 try { 1726 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, use, ops, alg, kid, x5u, x5t, x5c); 1727 1728 } catch (IllegalArgumentException ex) { 1729 1730 // Inconsistent 2nd spec, conflicting 'use' and 'key_ops' 1731 throw new ParseException(ex.getMessage(), 0); 1732 } 1733 } 1734}