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