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