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