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