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