001package com.nimbusds.jose.jwk; 002 003 004import java.net.URI; 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 com.nimbusds.jose.JOSEException; 026import net.jcip.annotations.Immutable; 027 028import net.minidev.json.JSONArray; 029import net.minidev.json.JSONObject; 030 031import com.nimbusds.jose.Algorithm; 032import com.nimbusds.jose.util.Base64; 033import com.nimbusds.jose.util.Base64URL; 034import com.nimbusds.jose.util.JSONObjectUtils; 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 2015-04-22 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 URI 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 URI 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 URI 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 URI 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 URI 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 URI 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 URI 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 URI 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 URI 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 URI 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 JOSEException If RSA is not supported by the underlying Java 1390 * Cryptography (JCA) provider or if the JWK 1391 * parameters are invalid for a public RSA key. 1392 */ 1393 public RSAPublicKey toRSAPublicKey() 1394 throws JOSEException { 1395 1396 BigInteger modulus = n.decodeToBigInteger(); 1397 BigInteger exponent = e.decodeToBigInteger(); 1398 1399 RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent); 1400 1401 try { 1402 KeyFactory factory = KeyFactory.getInstance("RSA"); 1403 1404 return (RSAPublicKey) factory.generatePublic(spec); 1405 1406 } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { 1407 1408 throw new JOSEException(e.getMessage(), e); 1409 } 1410 } 1411 1412 1413 /** 1414 * Returns a standard {@code java.security.interfaces.RSAPrivateKey} 1415 * representation of this RSA JWK. 1416 * 1417 * @return The private RSA key, {@code null} if not specified by this 1418 * JWK. 1419 * 1420 * @throws JOSEException If RSA is not supported by the underlying Java 1421 * Cryptography (JCA) provider or if the JWK 1422 * parameters are invalid for a private RSA key. 1423 */ 1424 public RSAPrivateKey toRSAPrivateKey() 1425 throws JOSEException { 1426 1427 if (d == null) { 1428 // no private key 1429 return null; 1430 } 1431 1432 BigInteger modulus = n.decodeToBigInteger(); 1433 BigInteger privateExponent = d.decodeToBigInteger(); 1434 1435 RSAPrivateKeySpec spec; 1436 1437 if (p == null) { 1438 // Use 1st representation 1439 spec = new RSAPrivateKeySpec(modulus, privateExponent); 1440 1441 } else { 1442 // Use 2nd (CRT) representation 1443 BigInteger publicExponent = e.decodeToBigInteger(); 1444 BigInteger primeP = p.decodeToBigInteger(); 1445 BigInteger primeQ = q.decodeToBigInteger(); 1446 BigInteger primeExponentP = dp.decodeToBigInteger(); 1447 BigInteger primeExponentQ = dq.decodeToBigInteger(); 1448 BigInteger crtCoefficient = qi.decodeToBigInteger(); 1449 1450 if (oth != null && ! oth.isEmpty()) { 1451 // Construct other info spec 1452 RSAOtherPrimeInfo[] otherInfo = new RSAOtherPrimeInfo[oth.size()]; 1453 1454 for (int i=0; i < oth.size(); i++) { 1455 1456 OtherPrimesInfo opi = oth.get(i); 1457 1458 BigInteger otherPrime = opi.getPrimeFactor().decodeToBigInteger(); 1459 BigInteger otherPrimeExponent = opi.getFactorCRTExponent().decodeToBigInteger(); 1460 BigInteger otherCrtCoefficient = opi.getFactorCRTCoefficient().decodeToBigInteger(); 1461 1462 otherInfo[i] = new RSAOtherPrimeInfo(otherPrime, 1463 otherPrimeExponent, 1464 otherCrtCoefficient); 1465 } 1466 1467 spec = new RSAMultiPrimePrivateCrtKeySpec(modulus, 1468 publicExponent, 1469 privateExponent, 1470 primeP, 1471 primeQ, 1472 primeExponentP, 1473 primeExponentQ, 1474 crtCoefficient, 1475 otherInfo); 1476 } else { 1477 // Construct spec with no other info 1478 spec = new RSAPrivateCrtKeySpec(modulus, 1479 publicExponent, 1480 privateExponent, 1481 primeP, 1482 primeQ, 1483 primeExponentP, 1484 primeExponentQ, 1485 crtCoefficient); 1486 } 1487 } 1488 1489 try { 1490 KeyFactory factory = KeyFactory.getInstance("RSA"); 1491 1492 return (RSAPrivateKey) factory.generatePrivate(spec); 1493 1494 } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 1495 1496 throw new JOSEException(e.getMessage(), e); 1497 } 1498 } 1499 1500 1501 /** 1502 * Returns a standard {@code java.security.KeyPair} representation of 1503 * this RSA JWK. 1504 * 1505 * @return The RSA key pair. The private RSA key will be {@code null} 1506 * if not specified. 1507 * 1508 * @throws JOSEException If RSA is not supported by the underlying Java 1509 * Cryptography (JCA) provider or if the JWK 1510 * parameters are invalid for a public and / or 1511 * private RSA key. 1512 */ 1513 public KeyPair toKeyPair() 1514 throws JOSEException { 1515 1516 return new KeyPair(toRSAPublicKey(), toRSAPrivateKey()); 1517 } 1518 1519 1520 @Override 1521 public boolean isPrivate() { 1522 1523 // Check if 1st or 2nd form params are specified 1524 return d != null || p != null; 1525 } 1526 1527 1528 /** 1529 * Returns a copy of this RSA JWK with any private values removed. 1530 * 1531 * @return The copied public RSA JWK. 1532 */ 1533 @Override 1534 public RSAKey toPublicJWK() { 1535 1536 return new RSAKey(getModulus(), getPublicExponent(), 1537 getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(), 1538 getX509CertURL(), getX509CertThumbprint(), getX509CertChain()); 1539 } 1540 1541 1542 @Override 1543 public JSONObject toJSONObject() { 1544 1545 JSONObject o = super.toJSONObject(); 1546 1547 // Append public RSA key specific attributes 1548 o.put("n", n.toString()); 1549 o.put("e", e.toString()); 1550 if (d != null) { 1551 o.put("d", d.toString()); 1552 } 1553 if (p != null) { 1554 o.put("p", p.toString()); 1555 } 1556 if (q != null) { 1557 o.put("q", q.toString()); 1558 } 1559 if (dp != null) { 1560 o.put("dp", dp.toString()); 1561 } 1562 if (dq != null) { 1563 o.put("dq", dq.toString()); 1564 } 1565 if (qi != null) { 1566 o.put("qi", qi.toString()); 1567 } 1568 if (oth != null && !oth.isEmpty()) { 1569 1570 JSONArray a = new JSONArray(); 1571 1572 for (OtherPrimesInfo other : oth) { 1573 1574 JSONObject oo = new JSONObject(); 1575 oo.put("r", other.r.toString()); 1576 oo.put("d", other.d.toString()); 1577 oo.put("t", other.t.toString()); 1578 1579 a.add(oo); 1580 } 1581 1582 o.put("oth", a); 1583 } 1584 1585 return o; 1586 } 1587 1588 1589 /** 1590 * Parses a public / private RSA Curve JWK from the specified JSON 1591 * object string representation. 1592 * 1593 * @param s The JSON object string to parse. Must not be {@code null}. 1594 * 1595 * @return The public / private RSA JWK. 1596 * 1597 * @throws ParseException If the string couldn't be parsed to an RSA 1598 * JWK. 1599 */ 1600 public static RSAKey parse(final String s) 1601 throws ParseException { 1602 1603 return parse(JSONObjectUtils.parseJSONObject(s)); 1604 } 1605 1606 1607 /** 1608 * Parses a public / private RSA JWK from the specified JSON object 1609 * representation. 1610 * 1611 * @param jsonObject The JSON object to parse. Must not be 1612 * @code null}. 1613 * 1614 * @return The public / private RSA Key. 1615 * 1616 * @throws ParseException If the JSON object couldn't be parsed to an 1617 * RSA JWK. 1618 */ 1619 public static RSAKey parse(final JSONObject jsonObject) 1620 throws ParseException { 1621 1622 // Parse the mandatory public key parameters first 1623 Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n")); 1624 Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e")); 1625 1626 // Check key type 1627 KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty")); 1628 if (kty != KeyType.RSA) { 1629 throw new ParseException("The key type \"kty\" must be RSA", 0); 1630 } 1631 1632 // Parse the optional private key parameters 1633 1634 // 1st private representation 1635 Base64URL d = null; 1636 if (jsonObject.containsKey("d")) { 1637 d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d")); 1638 } 1639 1640 // 2nd private (CRT) representation 1641 Base64URL p = null; 1642 if (jsonObject.containsKey("p")) { 1643 p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p")); 1644 } 1645 Base64URL q = null; 1646 if (jsonObject.containsKey("q")) { 1647 q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q")); 1648 } 1649 Base64URL dp = null; 1650 if (jsonObject.containsKey("dp")) { 1651 dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp")); 1652 } 1653 Base64URL dq= null; 1654 if (jsonObject.containsKey("dq")) { 1655 dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq")); 1656 } 1657 Base64URL qi = null; 1658 if (jsonObject.containsKey("qi")) { 1659 qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi")); 1660 } 1661 1662 List<OtherPrimesInfo> oth = null; 1663 if (jsonObject.containsKey("oth")) { 1664 1665 JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth"); 1666 oth = new ArrayList<>(arr.size()); 1667 1668 for (Object o : arr) { 1669 1670 if (o instanceof JSONObject) { 1671 JSONObject otherJson = (JSONObject)o; 1672 1673 Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r")); 1674 Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq")); 1675 Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t")); 1676 1677 OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t); 1678 oth.add(prime); 1679 } 1680 } 1681 } 1682 1683 try { 1684 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, 1685 JWKMetadata.parseKeyUse(jsonObject), 1686 JWKMetadata.parseKeyOperations(jsonObject), 1687 JWKMetadata.parseAlgorithm(jsonObject), 1688 JWKMetadata.parseKeyID(jsonObject), 1689 JWKMetadata.parseX509CertURL(jsonObject), 1690 JWKMetadata.parseX509CertThumbprint(jsonObject), 1691 JWKMetadata.parseX509CertChain(jsonObject)); 1692 1693 } catch (IllegalArgumentException ex) { 1694 1695 // Inconsistent 2nd spec, conflicting 'use' and 'key_ops' 1696 throw new ParseException(ex.getMessage(), 0); 1697 } 1698 } 1699}