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