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