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