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 2017-06-01 135 */ 136@Immutable 137public final class RSAKey extends JWK implements AssymetricJWK { 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 1336 this.n = n; 1337 1338 1339 if (e == null) { 1340 throw new IllegalArgumentException("The public exponent value must not be null"); 1341 } 1342 1343 this.e = e; 1344 1345 1346 // Private params, 1st representation 1347 1348 this.d = d; 1349 1350 1351 // Private params, 2nd representation, check for consistency 1352 1353 if (p != null && q != null && dp != null && dq != null && qi != null) { 1354 1355 // CRT params fully specified 1356 this.p = p; 1357 this.q = q; 1358 this.dp = dp; 1359 this.dq = dq; 1360 this.qi = qi; 1361 1362 // Other RSA primes info optional, default to empty list 1363 if (oth != null) { 1364 this.oth = Collections.unmodifiableList(oth); 1365 } else { 1366 this.oth = Collections.emptyList(); 1367 } 1368 1369 } else if (p == null && q == null && dp == null && dq == null && qi == null && oth == null) { 1370 1371 // No CRT params 1372 this.p = null; 1373 this.q = null; 1374 this.dp = null; 1375 this.dq = null; 1376 this.qi = null; 1377 1378 this.oth = Collections.emptyList(); 1379 1380 } else if (p != null || q != null || dp != null || dq != null || qi != null) { 1381 1382 if (p == null) { 1383 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first prime factor must not be null"); 1384 } else if (q == null) { 1385 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second prime factor must not be null"); 1386 } else if (dp == null) { 1387 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first factor CRT exponent must not be null"); 1388 } else if (dq == null) { 1389 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second factor CRT exponent must not be null"); 1390 } else { 1391 throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first CRT coefficient must not be null"); 1392 } 1393 } else { 1394 // No CRT params 1395 this.p = null; 1396 this.q = null; 1397 this.dp = null; 1398 this.dq = null; 1399 this.qi = null; 1400 this.oth = Collections.emptyList(); 1401 } 1402 1403 this.privateKey = prv; // PKCS#11 handle 1404 } 1405 1406 1407 /** 1408 * Creates a new public RSA JSON Web Key (JWK) with the specified 1409 * parameters. 1410 * 1411 * @param pub The public RSA key to represent. Must not be 1412 * {@code null}. 1413 * @param use The key use, {@code null} if not specified or if the 1414 * key is intended for signing as well as encryption. 1415 * @param ops The key operations, {@code null} if not specified. 1416 * @param alg The intended JOSE algorithm for the key, {@code null} 1417 * if not specified. 1418 * @param kid The key ID. {@code null} if not specified. 1419 * @param x5u The X.509 certificate URL, {@code null} if not 1420 * specified. 1421 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1422 * if not specified. 1423 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1424 * if not specified. 1425 * @param x5c The X.509 certificate chain, {@code null} if not 1426 * specified. 1427 * @param ks Reference to the underlying key store, {@code null} if 1428 * not specified. 1429 */ 1430 public RSAKey(final RSAPublicKey pub, 1431 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1432 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1433 final KeyStore ks) { 1434 1435 this(Base64URL.encode(pub.getModulus()), 1436 Base64URL.encode(pub.getPublicExponent()), 1437 use, ops, alg, kid, 1438 x5u, x5t, x5t256, x5c, 1439 ks); 1440 } 1441 1442 1443 /** 1444 * Creates a new public / private RSA JSON Web Key (JWK) with the 1445 * specified parameters. The private RSA key is specified by its first 1446 * representation (see RFC 3447, section 3.2). 1447 * 1448 * @param pub The public RSA key to represent. Must not be 1449 * {@code null}. 1450 * @param priv The private RSA key to represent. Must not be 1451 * {@code null}. 1452 * @param use The key use, {@code null} if not specified or if the 1453 * key is intended for signing as well as encryption. 1454 * @param ops The key operations, {@code null} if not specified. 1455 * @param alg The intended JOSE algorithm for the key, {@code null} 1456 * if not specified. 1457 * @param kid The key ID. {@code null} if not specified. 1458 * @param x5u The X.509 certificate URL, {@code null} if not 1459 * specified. 1460 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1461 * if not specified. 1462 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1463 * if not specified. 1464 * @param x5c The X.509 certificate chain, {@code null} if not 1465 * specified. 1466 * @param ks Reference to the underlying key store, {@code null} if 1467 * not specified. 1468 */ 1469 public RSAKey(final RSAPublicKey pub, final RSAPrivateKey priv, 1470 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1471 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1472 final KeyStore ks) { 1473 1474 this(Base64URL.encode(pub.getModulus()), 1475 Base64URL.encode(pub.getPublicExponent()), 1476 Base64URL.encode(priv.getPrivateExponent()), 1477 use, ops, alg, kid, 1478 x5u, x5t, x5t256, x5c, 1479 ks); 1480 } 1481 1482 1483 /** 1484 * Creates a new public / private RSA JSON Web Key (JWK) with the 1485 * specified parameters. The private RSA key is specified by its second 1486 * representation (see RFC 3447, section 3.2). 1487 * 1488 * @param pub The public RSA key to represent. Must not be 1489 * {@code null}. 1490 * @param priv The private RSA key to represent. Must not be 1491 * {@code null}. 1492 * @param use The key use, {@code null} if not specified or if the 1493 * key is intended for signing as well as encryption. 1494 * @param ops The key operations, {@code null} if not specified. 1495 * @param alg The intended JOSE algorithm for the key, {@code null} 1496 * if not specified. 1497 * @param kid The key ID. {@code null} if not specified. 1498 * @param x5u The X.509 certificate URL, {@code null} if not 1499 * specified. 1500 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1501 * if not specified. 1502 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1503 * if not specified. 1504 * @param x5c The X.509 certificate chain, {@code null} if not 1505 * specified. 1506 * @param ks Reference to the underlying key store, {@code null} if 1507 * not specified. 1508 */ 1509 public RSAKey(final RSAPublicKey pub, final RSAPrivateCrtKey priv, 1510 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1511 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1512 final KeyStore ks) { 1513 1514 this(Base64URL.encode(pub.getModulus()), 1515 Base64URL.encode(pub.getPublicExponent()), 1516 Base64URL.encode(priv.getPrivateExponent()), 1517 Base64URL.encode(priv.getPrimeP()), 1518 Base64URL.encode(priv.getPrimeQ()), 1519 Base64URL.encode(priv.getPrimeExponentP()), 1520 Base64URL.encode(priv.getPrimeExponentQ()), 1521 Base64URL.encode(priv.getCrtCoefficient()), 1522 null, 1523 null, 1524 use, ops, alg, kid, 1525 x5u, x5t, x5t256, x5c, 1526 ks); 1527 } 1528 1529 1530 /** 1531 * Creates a new public / private RSA JSON Web Key (JWK) with the 1532 * specified parameters. The private RSA key is specified by its second 1533 * representation, with optional other primes info (see RFC 3447, 1534 * section 3.2). 1535 * 1536 * @param pub The public RSA key to represent. Must not be 1537 * {@code null}. 1538 * @param priv The private RSA key to represent. Must not be 1539 * {@code null}. 1540 * @param use The key use, {@code null} if not specified or if the 1541 * key is intended for signing as well as encryption. 1542 * @param ops The key operations, {@code null} if not specified. 1543 * @param alg The intended JOSE algorithm for the key, {@code null} 1544 * if not specified. 1545 * @param kid The key ID. {@code null} if not specified. 1546 * @param x5u The X.509 certificate URL, {@code null} if not 1547 * specified. 1548 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1549 * if not specified. 1550 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1551 * if not specified. 1552 * @param x5c The X.509 certificate chain, {@code null} if not 1553 * specified. 1554 * @param ks Reference to the underlying key store, {@code null} if 1555 * not specified. 1556 */ 1557 public RSAKey(final RSAPublicKey pub, final RSAMultiPrimePrivateCrtKey priv, 1558 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1559 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1560 final KeyStore ks) { 1561 1562 this(Base64URL.encode(pub.getModulus()), 1563 Base64URL.encode(pub.getPublicExponent()), 1564 Base64URL.encode(priv.getPrivateExponent()), 1565 Base64URL.encode(priv.getPrimeP()), 1566 Base64URL.encode(priv.getPrimeQ()), 1567 Base64URL.encode(priv.getPrimeExponentP()), 1568 Base64URL.encode(priv.getPrimeExponentQ()), 1569 Base64URL.encode(priv.getCrtCoefficient()), 1570 OtherPrimesInfo.toList(priv.getOtherPrimeInfo()), 1571 null, 1572 use, ops, alg, kid, 1573 x5u, x5t, x5t256, x5c, 1574 ks); 1575 } 1576 1577 1578 /** 1579 * Creates a new public / private RSA JSON Web Key (JWK) with the 1580 * specified parameters. The private RSA key is specified by a PKCS#11 1581 * handle. 1582 * 1583 * @param pub The public RSA key to represent. Must not be 1584 * {@code null}. 1585 * @param priv The private RSA key as PKCS#11 handle, {@code null} if 1586 * not specified. 1587 * @param use The key use, {@code null} if not specified or if the 1588 * key is intended for signing as well as encryption. 1589 * @param ops The key operations, {@code null} if not specified. 1590 * @param alg The intended JOSE algorithm for the key, {@code null} 1591 * if not specified. 1592 * @param kid The key ID. {@code null} if not specified. 1593 * @param x5u The X.509 certificate URL, {@code null} if not 1594 * specified. 1595 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1596 * if not specified. 1597 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1598 * if not specified. 1599 * @param x5c The X.509 certificate chain, {@code null} if not 1600 * specified. 1601 * @param ks Reference to the underlying key store, {@code null} if 1602 * not specified. 1603 */ 1604 public RSAKey(final RSAPublicKey pub, final PrivateKey priv, 1605 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1606 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1607 final KeyStore ks) { 1608 1609 this(Base64URL.encode(pub.getModulus()), 1610 Base64URL.encode(pub.getPublicExponent()), 1611 null, 1612 null, 1613 null, 1614 null, 1615 null, 1616 null, 1617 null, 1618 priv, 1619 use, ops, alg, kid, 1620 x5u, x5t, x5t256, x5c, 1621 ks); 1622 } 1623 1624 1625 /** 1626 * Gets the modulus value ({@code n}) of the RSA key. 1627 * 1628 * @return The RSA key modulus. It is represented as the Base64URL 1629 * encoding of the value's big endian representation. 1630 */ 1631 public Base64URL getModulus() { 1632 1633 return n; 1634 } 1635 1636 1637 /** 1638 * Gets the public exponent ({@code e}) of the RSA key. 1639 * 1640 * @return The public RSA key exponent. It is represented as the 1641 * Base64URL encoding of the value's big endian representation. 1642 */ 1643 public Base64URL getPublicExponent() { 1644 1645 return e; 1646 } 1647 1648 1649 /** 1650 * Gets the private exponent ({@code d}) of the RSA key. 1651 * 1652 * @return The private RSA key exponent. It is represented as the 1653 * Base64URL encoding of the value's big endian representation. 1654 * {@code null} if not specified (for a public key or a private 1655 * key using the second representation only). 1656 */ 1657 public Base64URL getPrivateExponent() { 1658 1659 return d; 1660 } 1661 1662 1663 /** 1664 * Gets the first prime factor ({@code p}) of the private RSA key. 1665 * 1666 * @return The RSA first prime factor. It is represented as the 1667 * Base64URL encoding of the value's big endian representation. 1668 * {@code null} if not specified (for a public key or a private 1669 * key using the first representation only). 1670 */ 1671 public Base64URL getFirstPrimeFactor() { 1672 1673 return p; 1674 } 1675 1676 1677 /** 1678 * Gets the second prime factor ({@code q}) of the private RSA key. 1679 * 1680 * @return The RSA second prime factor. It is represented as the 1681 * Base64URL encoding of the value's big endian representation. 1682 * {@code null} if not specified (for a public key or a private 1683 * key using the first representation only). 1684 */ 1685 public Base64URL getSecondPrimeFactor() { 1686 1687 return q; 1688 } 1689 1690 1691 /** 1692 * Gets the first factor Chinese Remainder Theorem (CRT) exponent 1693 * ({@code dp}) of the private RSA key. 1694 * 1695 * @return The RSA first factor CRT exponent. It is represented as the 1696 * Base64URL encoding of the value's big endian representation. 1697 * {@code null} if not specified (for a public key or a private 1698 * key using the first representation only). 1699 */ 1700 public Base64URL getFirstFactorCRTExponent() { 1701 1702 return dp; 1703 } 1704 1705 1706 /** 1707 * Gets the second factor Chinese Remainder Theorem (CRT) exponent 1708 * ({@code dq}) of the private RSA key. 1709 * 1710 * @return The RSA second factor CRT exponent. It is represented as the 1711 * Base64URL encoding of the value's big endian representation. 1712 * {@code null} if not specified (for a public key or a private 1713 * key using the first representation only). 1714 */ 1715 public Base64URL getSecondFactorCRTExponent() { 1716 1717 return dq; 1718 } 1719 1720 1721 /** 1722 * Gets the first Chinese Remainder Theorem (CRT) coefficient 1723 * ({@code qi})} of the private RSA key. 1724 * 1725 * @return The RSA first CRT coefficient. It is represented as the 1726 * Base64URL encoding of the value's big endian representation. 1727 * {@code null} if not specified (for a public key or a private 1728 * key using the first representation only). 1729 */ 1730 public Base64URL getFirstCRTCoefficient() { 1731 1732 return qi; 1733 } 1734 1735 1736 /** 1737 * Gets the other primes information ({@code oth}) for the private RSA 1738 * key, should they exist. 1739 * 1740 * @return The RSA other primes information, {@code null} or empty list 1741 * if not specified. 1742 */ 1743 public List<OtherPrimesInfo> getOtherPrimes() { 1744 1745 return oth; 1746 } 1747 1748 1749 /** 1750 * Returns a standard {@code java.security.interfaces.RSAPublicKey} 1751 * representation of this RSA JWK. 1752 * 1753 * @return The public RSA key. 1754 * 1755 * @throws JOSEException If RSA is not supported by the underlying Java 1756 * Cryptography (JCA) provider or if the JWK 1757 * parameters are invalid for a public RSA key. 1758 */ 1759 public RSAPublicKey toRSAPublicKey() 1760 throws JOSEException { 1761 1762 BigInteger modulus = n.decodeToBigInteger(); 1763 BigInteger exponent = e.decodeToBigInteger(); 1764 1765 RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent); 1766 1767 try { 1768 KeyFactory factory = KeyFactory.getInstance("RSA"); 1769 1770 return (RSAPublicKey) factory.generatePublic(spec); 1771 1772 } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { 1773 1774 throw new JOSEException(e.getMessage(), e); 1775 } 1776 } 1777 1778 1779 /** 1780 * Returns a standard {@code java.security.interfaces.RSAPrivateKey} 1781 * representation of this RSA JWK. 1782 * 1783 * @return The private RSA key, {@code null} if not specified by this 1784 * JWK. 1785 * 1786 * @throws JOSEException If RSA is not supported by the underlying Java 1787 * Cryptography (JCA) provider or if the JWK 1788 * parameters are invalid for a private RSA key. 1789 */ 1790 public RSAPrivateKey toRSAPrivateKey() 1791 throws JOSEException { 1792 1793 if (d == null) { 1794 // no private key 1795 return null; 1796 } 1797 1798 BigInteger modulus = n.decodeToBigInteger(); 1799 BigInteger privateExponent = d.decodeToBigInteger(); 1800 1801 RSAPrivateKeySpec spec; 1802 1803 if (p == null) { 1804 // Use 1st representation 1805 spec = new RSAPrivateKeySpec(modulus, privateExponent); 1806 1807 } else { 1808 // Use 2nd (CRT) representation 1809 BigInteger publicExponent = e.decodeToBigInteger(); 1810 BigInteger primeP = p.decodeToBigInteger(); 1811 BigInteger primeQ = q.decodeToBigInteger(); 1812 BigInteger primeExponentP = dp.decodeToBigInteger(); 1813 BigInteger primeExponentQ = dq.decodeToBigInteger(); 1814 BigInteger crtCoefficient = qi.decodeToBigInteger(); 1815 1816 if (oth != null && ! oth.isEmpty()) { 1817 // Construct other info spec 1818 RSAOtherPrimeInfo[] otherInfo = new RSAOtherPrimeInfo[oth.size()]; 1819 1820 for (int i=0; i < oth.size(); i++) { 1821 1822 OtherPrimesInfo opi = oth.get(i); 1823 1824 BigInteger otherPrime = opi.getPrimeFactor().decodeToBigInteger(); 1825 BigInteger otherPrimeExponent = opi.getFactorCRTExponent().decodeToBigInteger(); 1826 BigInteger otherCrtCoefficient = opi.getFactorCRTCoefficient().decodeToBigInteger(); 1827 1828 otherInfo[i] = new RSAOtherPrimeInfo(otherPrime, 1829 otherPrimeExponent, 1830 otherCrtCoefficient); 1831 } 1832 1833 spec = new RSAMultiPrimePrivateCrtKeySpec(modulus, 1834 publicExponent, 1835 privateExponent, 1836 primeP, 1837 primeQ, 1838 primeExponentP, 1839 primeExponentQ, 1840 crtCoefficient, 1841 otherInfo); 1842 } else { 1843 // Construct spec with no other info 1844 spec = new RSAPrivateCrtKeySpec(modulus, 1845 publicExponent, 1846 privateExponent, 1847 primeP, 1848 primeQ, 1849 primeExponentP, 1850 primeExponentQ, 1851 crtCoefficient); 1852 } 1853 } 1854 1855 try { 1856 KeyFactory factory = KeyFactory.getInstance("RSA"); 1857 1858 return (RSAPrivateKey) factory.generatePrivate(spec); 1859 1860 } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 1861 1862 throw new JOSEException(e.getMessage(), e); 1863 } 1864 } 1865 1866 1867 @Override 1868 public PublicKey toPublicKey() 1869 throws JOSEException { 1870 1871 return toRSAPublicKey(); 1872 } 1873 1874 1875 @Override 1876 public PrivateKey toPrivateKey() 1877 throws JOSEException { 1878 1879 PrivateKey prv = toRSAPrivateKey(); 1880 1881 if (prv != null) { 1882 // Return private RSA key with key material 1883 return prv; 1884 } 1885 1886 // Return private RSA key as PKCS#11 handle, or null 1887 return privateKey; 1888 } 1889 1890 1891 /** 1892 * Returns a standard {@code java.security.KeyPair} representation of 1893 * this RSA JWK. 1894 * 1895 * @return The RSA key pair. The private RSA key will be {@code null} 1896 * if not specified. 1897 * 1898 * @throws JOSEException If RSA is not supported by the underlying Java 1899 * Cryptography (JCA) provider or if the JWK 1900 * parameters are invalid for a public and / or 1901 * private RSA key. 1902 */ 1903 @Override 1904 public KeyPair toKeyPair() 1905 throws JOSEException { 1906 1907 return new KeyPair(toRSAPublicKey(), toPrivateKey()); 1908 } 1909 1910 1911 @Override 1912 public LinkedHashMap<String,?> getRequiredParams() { 1913 1914 // Put mandatory params in sorted order 1915 LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>(); 1916 requiredParams.put("e", e.toString()); 1917 requiredParams.put("kty", getKeyType().getValue()); 1918 requiredParams.put("n", n.toString()); 1919 return requiredParams; 1920 } 1921 1922 1923 @Override 1924 public boolean isPrivate() { 1925 1926 // Check if 1st or 2nd form params are specified, or PKCS#11 handle 1927 return d != null || p != null || privateKey != null; 1928 } 1929 1930 1931 @Override 1932 public int size() { 1933 1934 try { 1935 return ByteUtils.safeBitLength(n.decode()); 1936 } catch (IntegerOverflowException e) { 1937 throw new ArithmeticException(e.getMessage()); 1938 } 1939 } 1940 1941 1942 /** 1943 * Returns a copy of this RSA JWK with any private values removed. 1944 * 1945 * @return The copied public RSA JWK. 1946 */ 1947 @Override 1948 public RSAKey toPublicJWK() { 1949 1950 return new RSAKey( 1951 getModulus(), getPublicExponent(), 1952 getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(), 1953 getX509CertURL(), getX509CertThumbprint(), getX509CertSHA256Thumbprint(), getX509CertChain(), 1954 getKeyStore()); 1955 } 1956 1957 1958 @Override 1959 public JSONObject toJSONObject() { 1960 1961 JSONObject o = super.toJSONObject(); 1962 1963 // Append public RSA key specific attributes 1964 o.put("n", n.toString()); 1965 o.put("e", e.toString()); 1966 if (d != null) { 1967 o.put("d", d.toString()); 1968 } 1969 if (p != null) { 1970 o.put("p", p.toString()); 1971 } 1972 if (q != null) { 1973 o.put("q", q.toString()); 1974 } 1975 if (dp != null) { 1976 o.put("dp", dp.toString()); 1977 } 1978 if (dq != null) { 1979 o.put("dq", dq.toString()); 1980 } 1981 if (qi != null) { 1982 o.put("qi", qi.toString()); 1983 } 1984 if (oth != null && !oth.isEmpty()) { 1985 1986 JSONArray a = new JSONArray(); 1987 1988 for (OtherPrimesInfo other : oth) { 1989 1990 JSONObject oo = new JSONObject(); 1991 oo.put("r", other.r.toString()); 1992 oo.put("d", other.d.toString()); 1993 oo.put("t", other.t.toString()); 1994 1995 a.add(oo); 1996 } 1997 1998 o.put("oth", a); 1999 } 2000 2001 return o; 2002 } 2003 2004 2005 /** 2006 * Parses a public / private RSA JWK from the specified JSON object 2007 * string representation. 2008 * 2009 * @param s The JSON object string to parse. Must not be {@code null}. 2010 * 2011 * @return The public / private RSA JWK. 2012 * 2013 * @throws ParseException If the string couldn't be parsed to an RSA 2014 * JWK. 2015 */ 2016 public static RSAKey parse(final String s) 2017 throws ParseException { 2018 2019 return parse(JSONObjectUtils.parse(s)); 2020 } 2021 2022 2023 /** 2024 * Parses a public / private RSA JWK from the specified JSON object 2025 * representation. 2026 * 2027 * @param jsonObject The JSON object to parse. Must not be 2028 * {@code null}. 2029 * 2030 * @return The public / private RSA Key. 2031 * 2032 * @throws ParseException If the JSON object couldn't be parsed to an 2033 * RSA JWK. 2034 */ 2035 public static RSAKey parse(final JSONObject jsonObject) 2036 throws ParseException { 2037 2038 // Parse the mandatory public key parameters first 2039 Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n")); 2040 Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e")); 2041 2042 // Check key type 2043 KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty")); 2044 if (kty != KeyType.RSA) { 2045 throw new ParseException("The key type \"kty\" must be RSA", 0); 2046 } 2047 2048 // Parse the optional private key parameters 2049 2050 // 1st private representation 2051 Base64URL d = null; 2052 if (jsonObject.containsKey("d")) { 2053 d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d")); 2054 } 2055 2056 // 2nd private (CRT) representation 2057 Base64URL p = null; 2058 if (jsonObject.containsKey("p")) { 2059 p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p")); 2060 } 2061 Base64URL q = null; 2062 if (jsonObject.containsKey("q")) { 2063 q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q")); 2064 } 2065 Base64URL dp = null; 2066 if (jsonObject.containsKey("dp")) { 2067 dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp")); 2068 } 2069 Base64URL dq= null; 2070 if (jsonObject.containsKey("dq")) { 2071 dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq")); 2072 } 2073 Base64URL qi = null; 2074 if (jsonObject.containsKey("qi")) { 2075 qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi")); 2076 } 2077 2078 List<OtherPrimesInfo> oth = null; 2079 if (jsonObject.containsKey("oth")) { 2080 2081 JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth"); 2082 oth = new ArrayList<>(arr.size()); 2083 2084 for (Object o : arr) { 2085 2086 if (o instanceof JSONObject) { 2087 JSONObject otherJson = (JSONObject)o; 2088 2089 Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r")); 2090 Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq")); 2091 Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t")); 2092 2093 OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t); 2094 oth.add(prime); 2095 } 2096 } 2097 } 2098 2099 try { 2100 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, null, 2101 JWKMetadata.parseKeyUse(jsonObject), 2102 JWKMetadata.parseKeyOperations(jsonObject), 2103 JWKMetadata.parseAlgorithm(jsonObject), 2104 JWKMetadata.parseKeyID(jsonObject), 2105 JWKMetadata.parseX509CertURL(jsonObject), 2106 JWKMetadata.parseX509CertThumbprint(jsonObject), 2107 JWKMetadata.parseX509CertSHA256Thumbprint(jsonObject), 2108 JWKMetadata.parseX509CertChain(jsonObject), 2109 null); 2110 2111 } catch (IllegalArgumentException ex) { 2112 2113 // Inconsistent 2nd spec, conflicting 'use' and 'key_ops' 2114 throw new ParseException(ex.getMessage(), 0); 2115 } 2116 } 2117 2118 2119 /** 2120 * Parses a public RSA JWK from the specified X.509 certificate. 2121 * 2122 * <p><strong>Important:</strong> The X.509 certificate is not 2123 * validated! 2124 * 2125 * <p>Sets the following JWK parameters: 2126 * 2127 * <ul> 2128 * <li>The JWK use inferred by {@link KeyUse#from}. 2129 * <li>The JWK ID from the X.509 serial number (in base 10). 2130 * <li>The JWK X.509 certificate chain (this certificate only). 2131 * <li>The JWK X.509 certificate SHA-256 thumbprint. 2132 * </ul> 2133 * 2134 * @param cert The X.509 certificate. Must not be {@code null}. 2135 * 2136 * @return The public RSA key. 2137 * 2138 * @throws JOSEException If parsing failed. 2139 */ 2140 public static RSAKey parse(final X509Certificate cert) 2141 throws JOSEException { 2142 2143 if (! (cert.getPublicKey() instanceof RSAPublicKey)) { 2144 throw new JOSEException("The public key of the X.509 certificate is not RSA"); 2145 } 2146 2147 RSAPublicKey publicKey = (RSAPublicKey)cert.getPublicKey(); 2148 2149 try { 2150 MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); 2151 2152 return new RSAKey.Builder(publicKey) 2153 .keyUse(KeyUse.from(cert)) 2154 .keyID(cert.getSerialNumber().toString(10)) 2155 .x509CertChain(Collections.singletonList(Base64.encode(cert.getEncoded()))) 2156 .x509CertSHA256Thumbprint(Base64URL.encode(sha256.digest(cert.getEncoded()))) 2157 .build(); 2158 } catch (NoSuchAlgorithmException e) { 2159 throw new JOSEException("Couldn't encode x5t parameter: " + e.getMessage(), e); 2160 } catch (CertificateEncodingException e) { 2161 throw new JOSEException("Couldn't encode x5c parameter: " + e.getMessage(), e); 2162 } 2163 } 2164 2165 2166 /** 2167 * Loads a public / private RSA JWK from the specified JCA key store. 2168 * 2169 * <p><strong>Important:</strong> The X.509 certificate is not 2170 * validated! 2171 * 2172 * @param keyStore The key store. Must not be {@code null}. 2173 * @param alias The alias. Must not be {@code null}. 2174 * @param pin The pin to unlock the private key if any, empty or 2175 * {@code null} if not required. 2176 * 2177 * @return The public / private RSA key, {@code null} if no key with 2178 * the specified alias was found. 2179 * 2180 * @throws KeyStoreException On a key store exception. 2181 * @throws JOSEException If RSA key loading failed. 2182 */ 2183 public static RSAKey load(final KeyStore keyStore, 2184 final String alias, 2185 final char[] pin) 2186 throws KeyStoreException, JOSEException { 2187 2188 java.security.cert.Certificate cert = keyStore.getCertificate(alias); 2189 2190 if (cert == null || ! (cert instanceof X509Certificate)) { 2191 return null; 2192 } 2193 2194 X509Certificate x509Cert = (X509Certificate)cert; 2195 2196 if (! (x509Cert.getPublicKey() instanceof RSAPublicKey)) { 2197 throw new JOSEException("Couldn't load RSA JWK: The key algorithm is not RSA"); 2198 } 2199 2200 RSAKey rsaJWK = RSAKey.parse(x509Cert); 2201 2202 // Let kid=alias 2203 rsaJWK = new RSAKey.Builder(rsaJWK).keyID(alias).keyStore(keyStore).build(); 2204 2205 // Check for private counterpart 2206 Key key; 2207 try { 2208 key = keyStore.getKey(alias, pin); 2209 } catch (UnrecoverableKeyException | NoSuchAlgorithmException e) { 2210 throw new JOSEException("Couldn't retrieve private RSA key (bad pin?): " + e.getMessage(), e); 2211 } 2212 2213 if (key instanceof RSAPrivateKey) { 2214 // Simple file based key store 2215 return new RSAKey.Builder(rsaJWK) 2216 .privateKey((RSAPrivateKey)key) 2217 .build(); 2218 } else if (key instanceof PrivateKey && "RSA".equalsIgnoreCase(key.getAlgorithm())) { 2219 // PKCS#11 store 2220 return new RSAKey.Builder(rsaJWK) 2221 .privateKey((PrivateKey)key) 2222 .build(); 2223 } else { 2224 return rsaJWK; 2225 } 2226 } 2227}