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