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