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.Base64URL; 039import com.nimbusds.jose.util.ByteUtils; 040import com.nimbusds.jose.util.JSONObjectUtils; 041import net.jcip.annotations.Immutable; 042import net.minidev.json.JSONArray; 043import net.minidev.json.JSONObject; 044 045 046/** 047 * Public and private {@link KeyType#RSA RSA} JSON Web Key (JWK). This class is 048 * immutable. 049 * 050 * <p>Provides RSA JWK import from / export to the following standard Java 051 * interfaces and classes: 052 * 053 * <ul> 054 * <li>{@link java.security.interfaces.RSAPublicKey} 055 * <li>{@link java.security.interfaces.RSAPrivateKey} 056 * <ul> 057 * <li>{@link java.security.interfaces.RSAPrivateCrtKey} 058 * <li>{@link java.security.interfaces.RSAMultiPrimePrivateCrtKey} 059 * </ul> 060 * <li>{@link java.security.PrivateKey} for an RSA key in a PKCS#11 store 061 * <li>{@link java.security.KeyPair} 062 * </ul> 063 * 064 * <p>Example JSON object representation of a public RSA JWK: 065 * 066 * <pre> 067 * { 068 * "kty" : "RSA", 069 * "n" : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 070 * 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs 071 * tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 072 * QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI 073 * SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb 074 * w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", 075 * "e" : "AQAB", 076 * "alg" : "RS256", 077 * "kid" : "2011-04-29" 078 * } 079 * </pre> 080 * 081 * <p>Example JSON object representation of a public and private RSA JWK (with 082 * both the first and the second private key representations): 083 * 084 * <pre> 085 * { 086 * "kty" : "RSA", 087 * "n" : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 088 * 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs 089 * tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 090 * QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI 091 * SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb 092 * w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", 093 * "e" : "AQAB", 094 * "d" : "X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9 095 * M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqij 096 * wp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d 097 * _cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBz 098 * nbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFz 099 * me1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q", 100 * "p" : "83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPV 101 * nwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqV 102 * WlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs", 103 * "q" : "3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyum 104 * qjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgx 105 * kIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk", 106 * "dp" : "G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oim 107 * YwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_Nmtu 108 * YZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0", 109 * "dq" : "s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUU 110 * vMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9 111 * GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk", 112 * "qi" : "GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzg 113 * UIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rx 114 * yR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU", 115 * "alg" : "RS256", 116 * "kid" : "2011-04-29" 117 * } 118 * </pre> 119 * 120 * <p>Use the builder to create a new RSA JWK: 121 * 122 * <pre> 123 * RSAKey key = new RSAKey.Builder(n, e) 124 * .keyUse(KeyUse.SIGNATURE) 125 * .keyID("123") 126 * .build(); 127 * </pre> 128 * 129 * <p>See RFC 3447. 130 * 131 * <p>See http://en.wikipedia.org/wiki/RSA_%28algorithm%29 132 * 133 * @author Vladimir Dzhuvinov 134 * @author Justin Richer 135 * @author Cedric Staub 136 * @version 2017-04-08 137 */ 138@Immutable 139public final class RSAKey extends JWK implements AssymetricJWK { 140 141 142 private static final long serialVersionUID = 1L; 143 144 145 /** 146 * Other Primes Info, represents the private {@code oth} parameter of a 147 * RSA JWK. This class is immutable. 148 */ 149 @Immutable 150 public static class OtherPrimesInfo implements Serializable { 151 152 153 private static final long serialVersionUID = 1L; 154 155 156 /** 157 * The prime factor. 158 */ 159 private final Base64URL r; 160 161 162 /** 163 * The factor Chinese Remainder Theorem (CRT) exponent. 164 */ 165 private final Base64URL d; 166 167 168 /** 169 * The factor Chinese Remainder Theorem (CRT) coefficient. 170 */ 171 private final Base64URL t; 172 173 174 /** 175 * Creates a new JWK Other Primes Info with the specified 176 * parameters. 177 * 178 * @param r The prime factor. Must not be {@code null}. 179 * @param d The factor Chinese Remainder Theorem (CRT) 180 * exponent. Must not be {@code null}. 181 * @param t The factor Chinese Remainder Theorem (CRT) 182 * coefficient. Must not be {@code null}. 183 */ 184 public OtherPrimesInfo(final Base64URL r, final Base64URL d, final Base64URL t) { 185 186 if (r == null) { 187 188 throw new IllegalArgumentException("The prime factor must not be null"); 189 } 190 191 this.r = r; 192 193 if (d == null) { 194 195 throw new IllegalArgumentException("The factor CRT exponent must not be null"); 196 } 197 198 this.d = d; 199 200 if (t == null) { 201 202 throw new IllegalArgumentException("The factor CRT coefficient must not be null"); 203 } 204 205 this.t = t; 206 } 207 208 209 /** 210 * Creates a new JWK Other Primes Info from the specified 211 * {@code java.security.spec.RSAOtherPrimeInfo} instance. 212 * 213 * @param oth The RSA Other Primes Info instance. Must not be 214 * {@code null}. 215 */ 216 public OtherPrimesInfo(final RSAOtherPrimeInfo oth) { 217 218 r = Base64URL.encode(oth.getPrime()); 219 d = Base64URL.encode(oth.getExponent()); 220 t = Base64URL.encode(oth.getCrtCoefficient()); 221 } 222 223 224 /** 225 * Gets the prime factor ({@code r}). 226 * 227 * @return The prime factor. 228 */ 229 public Base64URL getPrimeFactor() { 230 231 return r; 232 } 233 234 235 /** 236 * Gets factor Chinese Remainder Theorem (CRT) exponent 237 * ({@code d}). 238 * 239 * @return The factor Chinese Remainder Theorem (CRT) exponent. 240 */ 241 public Base64URL getFactorCRTExponent() { 242 243 return d; 244 } 245 246 247 /** 248 * The factor Chinese Remainder Theorem (CRT) coefficient 249 * ({@code t}). 250 * 251 * @return The factor Chinese Remainder Theorem (CRT) 252 * coefficient. 253 */ 254 public Base64URL getFactorCRTCoefficient() { 255 256 return t; 257 } 258 259 260 /** 261 * Converts the specified array of 262 * {@code java.security.spec.RSAOtherPrimeInfo} instances to a 263 * list of JWK Other Prime Infos. 264 * 265 * @param othArray Array of RSA Other Primes Info instances. 266 * May be be {@code null}. 267 * 268 * @return The corresponding list of JWK Other Prime Infos, or 269 * empty list of the array was {@code null}. 270 */ 271 public static List<OtherPrimesInfo> toList(final RSAOtherPrimeInfo[] othArray) { 272 273 List<OtherPrimesInfo> list = new ArrayList<>(); 274 275 if (othArray == null) { 276 277 // Return empty list 278 return list; 279 } 280 281 for (RSAOtherPrimeInfo oth: othArray) { 282 283 list.add(new OtherPrimesInfo(oth)); 284 } 285 286 return list; 287 } 288 } 289 290 291 /** 292 * Builder for constructing RSA JWKs. 293 * 294 * <p>Example usage: 295 * 296 * <pre> 297 * RSAKey key = new RSAKey.Builder(n, e). 298 * privateExponent(d). 299 * algorithm(JWSAlgorithm.RS512). 300 * keyID("456"). 301 * build(); 302 * </pre> 303 */ 304 public static class Builder { 305 306 307 // Public RSA params 308 309 /** 310 * The modulus value for the RSA key. 311 */ 312 private final Base64URL n; 313 314 315 /** 316 * The public exponent of the RSA key. 317 */ 318 private final Base64URL e; 319 320 321 // Private RSA params, 1st representation 322 323 /** 324 * The private exponent of the RSA key. 325 */ 326 private Base64URL d; 327 328 329 // Private RSA params, 2nd representation 330 331 /** 332 * The first prime factor of the private RSA key. 333 */ 334 private Base64URL p; 335 336 337 /** 338 * The second prime factor of the private RSA key. 339 */ 340 private Base64URL q; 341 342 343 /** 344 * The first factor Chinese Remainder Theorem exponent of the 345 * private RSA key. 346 */ 347 private Base64URL dp; 348 349 350 /** 351 * The second factor Chinese Remainder Theorem exponent of the 352 * private RSA key. 353 */ 354 private Base64URL dq; 355 356 357 /** 358 * The first Chinese Remainder Theorem coefficient of the private RSA 359 * key. 360 */ 361 private Base64URL qi; 362 363 364 /** 365 * The other primes information of the private RSA key, should 366 * they exist. When only two primes have been used (the normal 367 * case), this parameter MUST be omitted. When three or more 368 * primes have been used, the number of array elements MUST be 369 * the number of primes used minus two. 370 */ 371 private List<OtherPrimesInfo> oth; 372 373 374 // Private RSA key, as PKCS#11 handle 375 376 /** 377 * The private RSA key, as PKCS#11 handle. 378 */ 379 private PrivateKey priv; 380 381 382 /** 383 * The key use, optional. 384 */ 385 private KeyUse use; 386 387 388 /** 389 * The key operations, optional. 390 */ 391 private Set<KeyOperation> ops; 392 393 394 /** 395 * The intended JOSE algorithm for the key, optional. 396 */ 397 private Algorithm alg; 398 399 400 /** 401 * The key ID, optional. 402 */ 403 private String kid; 404 405 406 /** 407 * X.509 certificate URL, optional. 408 */ 409 private URI x5u; 410 411 412 /** 413 * X.509 certificate SHA-1 thumbprint, optional. 414 */ 415 @Deprecated 416 private Base64URL x5t; 417 418 419 /** 420 * X.509 certificate SHA-256 thumbprint, optional. 421 */ 422 private Base64URL x5t256; 423 424 425 /** 426 * The X.509 certificate chain, optional. 427 */ 428 private List<Base64> x5c; 429 430 431 /** 432 * Reference to the underlying key store, {@code null} if none. 433 */ 434 private KeyStore ks; 435 436 437 /** 438 * Creates a new RSA JWK builder. 439 * 440 * @param n The the modulus value for the public RSA key. It is 441 * represented as the Base64URL encoding of value's 442 * big endian representation. Must not be 443 * {@code null}. 444 * @param e The exponent value for the public RSA key. It is 445 * represented as the Base64URL encoding of value's 446 * big endian representation. Must not be 447 * {@code null}. 448 */ 449 public Builder(final Base64URL n, final Base64URL e) { 450 451 // Ensure the public params are defined 452 453 if (n == null) { 454 throw new IllegalArgumentException("The modulus value must not be null"); 455 } 456 457 this.n = n; 458 459 460 if (e == null) { 461 throw new IllegalArgumentException("The public exponent value must not be null"); 462 } 463 464 this.e = e; 465 } 466 467 468 /** 469 * Creates a new RSA JWK builder. 470 * 471 * @param pub The public RSA key to represent. Must not be 472 * {@code null}. 473 */ 474 public Builder(final RSAPublicKey pub) { 475 476 n = Base64URL.encode(pub.getModulus()); 477 e = Base64URL.encode(pub.getPublicExponent()); 478 } 479 480 481 /** 482 * Creates a new RSA JWK builder. 483 * 484 * @param rsaJWK The RSA JWK to start with. Must not be 485 * {@code null}. 486 */ 487 public Builder(final RSAKey rsaJWK) { 488 489 n = rsaJWK.n; 490 e = rsaJWK.e; 491 d = rsaJWK.d; 492 p = rsaJWK.p; 493 q = rsaJWK.q; 494 dp = rsaJWK.dp; 495 dq = rsaJWK.dq; 496 qi = rsaJWK.qi; 497 oth = rsaJWK.oth; 498 priv = rsaJWK.privateKey; 499 use = rsaJWK.getKeyUse(); 500 ops = rsaJWK.getKeyOperations(); 501 alg = rsaJWK.getAlgorithm(); 502 kid = rsaJWK.getKeyID(); 503 x5u = rsaJWK.getX509CertURL(); 504 x5t = rsaJWK.getX509CertThumbprint(); 505 x5t256 = rsaJWK.getX509CertSHA256Thumbprint(); 506 x5c = rsaJWK.getX509CertChain(); 507 ks = rsaJWK.getKeyStore(); 508 } 509 510 511 /** 512 * Sets the private exponent ({@code d}) of the RSA key. 513 * 514 * @param d The private RSA key exponent. It is represented as 515 * the Base64URL encoding of the value's big endian 516 * representation. {@code null} if not specified (for 517 * a public key or a private key using the second 518 * representation only). 519 * 520 * @return This builder. 521 */ 522 public Builder privateExponent(final Base64URL d) { 523 524 this.d = d; 525 return this; 526 } 527 528 529 /** 530 * Sets the private RSA key, using the first representation. 531 * 532 * @param priv The private RSA key, used to obtain the private 533 * exponent ({@code d}). Must not be {@code null}. 534 * 535 * @return This builder. 536 */ 537 public Builder privateKey(final RSAPrivateKey priv) { 538 539 if (priv instanceof RSAPrivateCrtKey) { 540 return this.privateKey((RSAPrivateCrtKey) priv); 541 } else if (priv instanceof RSAMultiPrimePrivateCrtKey) { 542 return this.privateKey((RSAMultiPrimePrivateCrtKey) priv); 543 } else { 544 this.d = Base64URL.encode(priv.getPrivateExponent()); 545 return this; 546 } 547 } 548 549 550 /** 551 * Sets the private RSA key, typically for a key located in a 552 * PKCS#11 store that doesn't expose the private key parameters 553 * (such as a smart card or HSM). 554 * 555 * @param priv The private RSA key reference. Its algorithm 556 * must be "RSA". Must not be {@code null}. 557 * 558 * @return This builder. 559 */ 560 public Builder privateKey(final PrivateKey priv) { 561 562 if (! "RSA".equalsIgnoreCase(priv.getAlgorithm())) { 563 throw new IllegalArgumentException("The private key algorithm must be RSA"); 564 } 565 566 this.priv = priv; 567 return this; 568 } 569 570 571 /** 572 * Sets the first prime factor ({@code p}) of the private RSA 573 * key. 574 * 575 * @param p The RSA first prime factor. It is represented as 576 * the Base64URL encoding of the value's big endian 577 * representation. {@code null} if not specified (for 578 * a public key or a private key using the first 579 * representation only). 580 * 581 * @return This builder. 582 */ 583 public Builder firstPrimeFactor(final Base64URL p) { 584 585 this.p = p; 586 return this; 587 } 588 589 590 /** 591 * Sets the second prime factor ({@code q}) of the private RSA 592 * key. 593 * 594 * @param q The RSA second prime factor. It is represented as 595 * the Base64URL encoding of the value's big endian 596 * representation. {@code null} if not specified (for 597 * a public key or a private key using the first 598 * representation only). 599 * 600 * @return This builder. 601 */ 602 public Builder secondPrimeFactor(final Base64URL q) { 603 604 this.q = q; 605 return this; 606 } 607 608 609 /** 610 * Sets the first factor Chinese Remainder Theorem (CRT) 611 * exponent ({@code dp}) of the private RSA key. 612 * 613 * @param dp The RSA first factor CRT exponent. It is 614 * represented as the Base64URL encoding of the 615 * value's big endian representation. {@code null} 616 * if not specified (for a public key or a private 617 * key using the first representation only). 618 * 619 * @return This builder. 620 */ 621 public Builder firstFactorCRTExponent(final Base64URL dp) { 622 623 this.dp = dp; 624 return this; 625 } 626 627 628 /** 629 * Sets the second factor Chinese Remainder Theorem (CRT) 630 * exponent ({@code dq}) of the private RSA key. 631 * 632 * @param dq The RSA second factor CRT exponent. It is 633 * represented as the Base64URL encoding of the 634 * value's big endian representation. {@code null} if 635 * not specified (for a public key or a private key 636 * using the first representation only). 637 * 638 * @return This builder. 639 */ 640 public Builder secondFactorCRTExponent(final Base64URL dq) { 641 642 this.dq = dq; 643 return this; 644 } 645 646 647 /** 648 * Sets the first Chinese Remainder Theorem (CRT) coefficient 649 * ({@code qi})} of the private RSA key. 650 * 651 * @param qi The RSA first CRT coefficient. It is represented 652 * as the Base64URL encoding of the value's big 653 * endian representation. {@code null} if not 654 * specified (for a public key or a private key using 655 * the first representation only). 656 * 657 * @return This builder. 658 */ 659 public Builder firstCRTCoefficient(final Base64URL qi) { 660 661 this.qi = qi; 662 return this; 663 } 664 665 666 /** 667 * Sets the other primes information ({@code oth}) for the 668 * private RSA key, should they exist. 669 * 670 * @param oth The RSA other primes information, {@code null} or 671 * empty list if not specified. 672 * 673 * @return This builder. 674 */ 675 public Builder otherPrimes(final List<OtherPrimesInfo> oth) { 676 677 this.oth = oth; 678 return this; 679 } 680 681 682 /** 683 * Sets the private RSA key, using the second representation 684 * (see RFC 3447, section 3.2). 685 * 686 * @param priv The private RSA key, used to obtain the private 687 * exponent ({@code d}), the first prime factor 688 * ({@code p}), the second prime factor 689 * ({@code q}), the first factor CRT exponent 690 * ({@code dp}), the second factor CRT exponent 691 * ({@code dq}) and the first CRT coefficient 692 * ({@code qi}). Must not be {@code null}. 693 * 694 * @return This builder. 695 */ 696 public Builder privateKey(final RSAPrivateCrtKey priv) { 697 698 d = Base64URL.encode(priv.getPrivateExponent()); 699 p = Base64URL.encode(priv.getPrimeP()); 700 q = Base64URL.encode(priv.getPrimeQ()); 701 dp = Base64URL.encode(priv.getPrimeExponentP()); 702 dq = Base64URL.encode(priv.getPrimeExponentQ()); 703 qi = Base64URL.encode(priv.getCrtCoefficient()); 704 705 return this; 706 } 707 708 709 /** 710 * Sets the private RSA key, using the second representation, 711 * with optional other primes info (see RFC 3447, section 3.2). 712 * 713 * @param priv The private RSA key, used to obtain the private 714 * exponent ({@code d}), the first prime factor 715 * ({@code p}), the second prime factor 716 * ({@code q}), the first factor CRT exponent 717 * ({@code dp}), the second factor CRT exponent 718 * ({@code dq}), the first CRT coefficient 719 * ({@code qi}) and the other primes info 720 * ({@code oth}). Must not be {@code null}. 721 * 722 * @return This builder. 723 */ 724 public Builder privateKey(final RSAMultiPrimePrivateCrtKey priv) { 725 726 d = Base64URL.encode(priv.getPrivateExponent()); 727 p = Base64URL.encode(priv.getPrimeP()); 728 q = Base64URL.encode(priv.getPrimeQ()); 729 dp = Base64URL.encode(priv.getPrimeExponentP()); 730 dq = Base64URL.encode(priv.getPrimeExponentQ()); 731 qi = Base64URL.encode(priv.getCrtCoefficient()); 732 oth = OtherPrimesInfo.toList(priv.getOtherPrimeInfo()); 733 734 return this; 735 } 736 737 738 /** 739 * Sets the use ({@code use}) of the JWK. 740 * 741 * @param use The key use, {@code null} if not specified or if 742 * the key is intended for signing as well as 743 * encryption. 744 * 745 * @return This builder. 746 */ 747 public Builder keyUse(final KeyUse use) { 748 749 this.use = use; 750 return this; 751 } 752 753 754 /** 755 * Sets the operations ({@code key_ops}) of the JWK (for a 756 * non-public key). 757 * 758 * @param ops The key operations, {@code null} if not 759 * specified. 760 * 761 * @return This builder. 762 */ 763 public Builder keyOperations(final Set<KeyOperation> ops) { 764 765 this.ops = ops; 766 return this; 767 } 768 769 770 /** 771 * Sets the intended JOSE algorithm ({@code alg}) for the JWK. 772 * 773 * @param alg The intended JOSE algorithm, {@code null} if not 774 * specified. 775 * 776 * @return This builder. 777 */ 778 public Builder algorithm(final Algorithm alg) { 779 780 this.alg = alg; 781 return this; 782 } 783 784 /** 785 * Sets the ID ({@code kid}) of the JWK. The key ID can be used 786 * to match a specific key. This can be used, for instance, to 787 * choose a key within a {@link JWKSet} during key rollover. 788 * The key ID may also correspond to a JWS/JWE {@code kid} 789 * header parameter value. 790 * 791 * @param kid The key ID, {@code null} if not specified. 792 * 793 * @return This builder. 794 */ 795 public Builder keyID(final String kid) { 796 797 this.kid = kid; 798 return this; 799 } 800 801 802 /** 803 * Sets the ID ({@code kid}) of the JWK to its SHA-256 JWK 804 * thumbprint (RFC 7638). The key ID can be used to match a 805 * specific key. This can be used, for instance, to choose a 806 * key within a {@link JWKSet} during key rollover. The key ID 807 * may also correspond to a JWS/JWE {@code kid} header 808 * parameter value. 809 * 810 * @return This builder. 811 * 812 * @throws JOSEException If the SHA-256 hash algorithm is not 813 * supported. 814 */ 815 public Builder keyIDFromThumbprint() 816 throws JOSEException { 817 818 return keyIDFromThumbprint("SHA-256"); 819 } 820 821 822 /** 823 * Sets the ID ({@code kid}) of the JWK to its JWK thumbprint 824 * (RFC 7638). The key ID can be used to match a specific key. 825 * This can be used, for instance, to choose a key within a 826 * {@link JWKSet} during key rollover. The key ID may also 827 * correspond to a JWS/JWE {@code kid} header parameter value. 828 * 829 * @param hashAlg The hash algorithm for the JWK thumbprint 830 * computation. Must not be {@code null}. 831 * 832 * @return This builder. 833 * 834 * @throws JOSEException If the hash algorithm is not 835 * supported. 836 */ 837 public Builder keyIDFromThumbprint(final String hashAlg) 838 throws JOSEException { 839 840 // Put mandatory params in sorted order 841 LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>(); 842 requiredParams.put("e", e.toString()); 843 requiredParams.put("kty", KeyType.RSA.getValue()); 844 requiredParams.put("n", n.toString()); 845 this.kid = ThumbprintUtils.compute(hashAlg, requiredParams).toString(); 846 return this; 847 } 848 849 850 /** 851 * Sets the X.509 certificate URL ({@code x5u}) of the JWK. 852 * 853 * @param x5u The X.509 certificate URL, {@code null} if not 854 * specified. 855 * 856 * @return This builder. 857 */ 858 public Builder x509CertURL(final URI x5u) { 859 860 this.x5u = x5u; 861 return this; 862 } 863 864 865 /** 866 * Sets the X.509 certificate SHA-1 thumbprint ({@code x5t}) of 867 * the JWK. 868 * 869 * @param x5t The X.509 certificate SHA-1 thumbprint, 870 * {@code null} if not specified. 871 * 872 * @return This builder. 873 */ 874 @Deprecated 875 public Builder x509CertThumbprint(final Base64URL x5t) { 876 877 this.x5t = x5t; 878 return this; 879 } 880 881 882 /** 883 * Sets the X.509 certificate SHA-256 thumbprint 884 * ({@code x5t#S256}) of the JWK. 885 * 886 * @param x5t256 The X.509 certificate SHA-256 thumbprint, 887 * {@code null} if not specified. 888 * 889 * @return This builder. 890 */ 891 public Builder x509CertSHA256Thumbprint(final Base64URL x5t256) { 892 893 this.x5t256 = x5t256; 894 return this; 895 } 896 897 898 /** 899 * Sets the X.509 certificate chain ({@code x5c}) of the JWK. 900 * 901 * @param x5c The X.509 certificate chain as a unmodifiable 902 * list, {@code null} if not specified. 903 * 904 * @return This builder. 905 */ 906 public Builder x509CertChain(final List<Base64> x5c) { 907 908 this.x5c = x5c; 909 return this; 910 } 911 912 913 /** 914 * Sets the underlying key store. 915 * 916 * @param keyStore Reference to the underlying key store, 917 * {@code null} if none. 918 * 919 * @return This builder. 920 */ 921 public Builder keyStore(final KeyStore keyStore) { 922 923 this.ks = keyStore; 924 return this; 925 } 926 927 928 /** 929 * Builds a new RSA JWK. 930 * 931 * @return The RSA JWK. 932 * 933 * @throws IllegalStateException If the JWK parameters were 934 * inconsistently specified. 935 */ 936 public RSAKey build() { 937 938 try { 939 // The full constructor 940 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, 941 priv, 942 use, ops, alg, kid, x5u, x5t, x5t256, x5c, 943 ks); 944 945 } catch (IllegalArgumentException e) { 946 947 throw new IllegalStateException(e.getMessage(), e); 948 } 949 } 950 } 951 952 953 // Public RSA params 954 955 /** 956 * The modulus value of the RSA key. 957 */ 958 private final Base64URL n; 959 960 961 /** 962 * The public exponent of the RSA key. 963 */ 964 private final Base64URL e; 965 966 967 // Private RSA params, 1st representation 968 969 /** 970 * The private exponent of the RSA key. 971 */ 972 private final Base64URL d; 973 974 975 // Private RSA params, 2nd representation 976 977 /** 978 * The first prime factor of the private RSA key. 979 */ 980 private final Base64URL p; 981 982 983 /** 984 * The second prime factor of the private RSA key. 985 */ 986 private final Base64URL q; 987 988 989 /** 990 * The first factor Chinese Remainder Theorem exponent of the private 991 * RSA key. 992 */ 993 private final Base64URL dp; 994 995 996 /** 997 * The second factor Chinese Remainder Theorem exponent of the private 998 * RSA key. 999 */ 1000 private final Base64URL dq; 1001 1002 1003 /** 1004 * The first Chinese Remainder Theorem coefficient of the private RSA 1005 * key. 1006 */ 1007 private final Base64URL qi; 1008 1009 1010 /** 1011 * The other primes information of the private RSA key, should they 1012 * exist. When only two primes have been used (the normal case), this 1013 * parameter MUST be omitted. When three or more primes have been used, 1014 * the number of array elements MUST be the number of primes used minus 1015 * two. 1016 */ 1017 private final List<OtherPrimesInfo> oth; 1018 1019 1020 // Private RSA PKCS#11 key handle 1021 1022 /** 1023 * Private PKCS#11 key handle. 1024 */ 1025 private final PrivateKey privateKey; 1026 1027 1028 /** 1029 * Creates a new public RSA JSON Web Key (JWK) with the specified 1030 * parameters. 1031 * 1032 * @param n The the modulus value for the public RSA key. It is 1033 * represented as the Base64URL encoding of value's big 1034 * endian representation. Must not be {@code null}. 1035 * @param e The exponent value for the public RSA key. It is 1036 * represented as the Base64URL encoding of value's big 1037 * endian representation. Must not be {@code null}. 1038 * @param use The key use, {@code null} if not specified or if the 1039 * key is intended for signing as well as encryption. 1040 * @param ops The key operations, {@code null} if not specified. 1041 * @param alg The intended JOSE algorithm for the key, {@code null} 1042 * if not specified. 1043 * @param kid The key ID. {@code null} if not specified. 1044 * @param x5u The X.509 certificate URL, {@code null} if not 1045 * specified. 1046 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1047 * if not specified. 1048 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1049 * if not specified. 1050 * @param x5c The X.509 certificate chain, {@code null} if not 1051 * specified. 1052 * @param ks Reference to the underlying key store, {@code null} if 1053 * not specified. 1054 */ 1055 public RSAKey(final Base64URL n, final Base64URL e, 1056 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1057 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1058 final KeyStore ks) { 1059 1060 // Call the full constructor, all private key parameters are null 1061 this(n, e, null, null, null, null, null, null, null, null, use, ops, alg, kid, 1062 x5u, x5t, x5t256, x5c, 1063 ks); 1064 } 1065 1066 1067 /** 1068 * Creates a new public / private RSA JSON Web Key (JWK) with the 1069 * specified parameters. The private RSA key is specified by its first 1070 * representation (see RFC 3447, section 3.2). 1071 * 1072 * @param n The the modulus value for the public RSA key. It is 1073 * represented as the Base64URL encoding of value's big 1074 * endian representation. Must not be {@code null}. 1075 * @param e The exponent value for the public RSA key. It is 1076 * represented as the Base64URL encoding of value's big 1077 * endian representation. Must not be {@code null}. 1078 * @param d The private exponent. It is represented as the 1079 * Base64URL encoding of the value's big endian 1080 * representation. Must not be {@code null}. 1081 * @param use The key use, {@code null} if not specified or if the 1082 * key is intended for signing as well as encryption. 1083 * @param ops The key operations, {@code null} if not specified. 1084 * @param alg The intended JOSE algorithm for the key, {@code null} 1085 * if not specified. 1086 * @param kid The key ID. {@code null} if not specified. 1087 * @param x5u The X.509 certificate URL, {@code null} if not 1088 * specified. 1089 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1090 * if not specified. 1091 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1092 * if not specified. 1093 * @param x5c The X.509 certificate chain, {@code null} if not 1094 * specified. 1095 * @param ks Reference to the underlying key store, {@code null} if 1096 * not specified. 1097 */ 1098 public RSAKey(final Base64URL n, final Base64URL e, final Base64URL d, 1099 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1100 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1101 final KeyStore ks) { 1102 1103 // Call the full constructor, the second private representation 1104 // parameters are all null 1105 this(n, e, d, null, null, null, null, null, null, null, use, ops, alg, kid, 1106 x5u, x5t, x5t256, x5c, ks); 1107 1108 if (d == null) { 1109 throw new IllegalArgumentException("The private exponent must not be null"); 1110 } 1111 } 1112 1113 1114 /** 1115 * Creates a new public / private RSA JSON Web Key (JWK) with the 1116 * specified parameters. The private RSA key is specified by its 1117 * second representation (see RFC 3447, section 3.2). 1118 * 1119 * @param n The the modulus value for the public RSA key. It is 1120 * represented as the Base64URL encoding of value's big 1121 * endian representation. Must not be {@code null}. 1122 * @param e The exponent value for the public RSA key. It is 1123 * represented as the Base64URL encoding of value's big 1124 * endian representation. Must not be {@code null}. 1125 * @param p The first prime factor. It is represented as the 1126 * Base64URL encoding of the value's big endian 1127 * representation. Must not be {@code null}. 1128 * @param q The second prime factor. It is represented as the 1129 * Base64URL encoding of the value's big endian 1130 * representation. Must not be {@code null}. 1131 * @param dp The first factor Chinese Remainder Theorem exponent. 1132 * It is represented as the Base64URL encoding of the 1133 * value's big endian representation. Must not be 1134 * {@code null}. 1135 * @param dq The second factor Chinese Remainder Theorem exponent. 1136 * It is represented as the Base64URL encoding of the 1137 * value's big endian representation. Must not be 1138 * {@code null}. 1139 * @param qi The first Chinese Remainder Theorem coefficient. It is 1140 * represented as the Base64URL encoding of the value's 1141 * big endian representation. Must not be {@code null}. 1142 * @param oth The other primes information, should they exist, 1143 * {@code null} or an empty list if not specified. 1144 * @param use The key use, {@code null} if not specified or if the 1145 * key is intended for signing as well as encryption. 1146 * @param ops The key operations, {@code null} if not specified. 1147 * @param alg The intended JOSE algorithm for the key, {@code null} 1148 * if not specified. 1149 * @param kid The key ID. {@code null} if not specified. 1150 * @param x5u The X.509 certificate URL, {@code null} if not 1151 * specified. 1152 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1153 * if not specified. 1154 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1155 * if not specified. 1156 * @param x5c The X.509 certificate chain, {@code null} if not 1157 * specified. 1158 * @param ks Reference to the underlying key store, {@code null} if 1159 * not specified. 1160 */ 1161 public RSAKey(final Base64URL n, final Base64URL e, 1162 final Base64URL p, final Base64URL q, 1163 final Base64URL dp, final Base64URL dq, final Base64URL qi, 1164 final List<OtherPrimesInfo> oth, 1165 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1166 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1167 final KeyStore ks) { 1168 1169 // Call the full constructor, the first private representation 1170 // d param is null 1171 this(n, e, null, p, q, dp, dq, qi, oth, null, use, ops, alg, kid, 1172 x5u, x5t, x5t256, x5c, 1173 ks); 1174 1175 if (p == null) { 1176 throw new IllegalArgumentException("The first prime factor must not be null"); 1177 } 1178 1179 if (q == null) { 1180 throw new IllegalArgumentException("The second prime factor must not be null"); 1181 } 1182 1183 if (dp == null) { 1184 throw new IllegalArgumentException("The first factor CRT exponent must not be null"); 1185 } 1186 1187 if (dq == null) { 1188 throw new IllegalArgumentException("The second factor CRT exponent must not be null"); 1189 } 1190 1191 if (qi == null) { 1192 throw new IllegalArgumentException("The first CRT coefficient must not be null"); 1193 } 1194 } 1195 1196 1197 /** 1198 * Creates a new public / private RSA JSON Web Key (JWK) with the 1199 * specified parameters. The private RSA key is specified by both its 1200 * first and second representations (see RFC 3447, section 3.2). 1201 * 1202 * <p>A valid first private RSA key representation must specify the 1203 * {@code d} parameter. 1204 * 1205 * <p>A valid second private RSA key representation must specify all 1206 * required Chinese Remainder Theorem (CRT) parameters - {@code p}, 1207 * {@code q}, {@code dp}, {@code dq} and {@code qi}, else an 1208 * {@link java.lang.IllegalArgumentException} will be thrown. 1209 * 1210 * @param n The the modulus value for the public RSA key. It is 1211 * represented as the Base64URL encoding of value's big 1212 * endian representation. Must not be {@code null}. 1213 * @param e The exponent value for the public RSA key. It is 1214 * represented as the Base64URL encoding of value's big 1215 * endian representation. Must not be {@code null}. 1216 * @param d The private exponent. It is represented as the Base64URL 1217 * encoding of the value's big endian representation. May 1218 * be {@code null}. 1219 * @param p The first prime factor. It is represented as the 1220 * Base64URL encoding of the value's big endian 1221 * representation. May be {@code null}. 1222 * @param q The second prime factor. It is represented as the 1223 * Base64URL encoding of the value's big endian 1224 * representation. May be {@code null}. 1225 * @param dp The first factor Chinese Remainder Theorem exponent. It 1226 * is represented as the Base64URL encoding of the value's 1227 * big endian representation. May be {@code null}. 1228 * @param dq The second factor Chinese Remainder Theorem exponent. It 1229 * is represented as the Base64URL encoding of the value's 1230 * big endian representation. May be {@code null}. 1231 * @param qi The first Chinese Remainder Theorem coefficient. It is 1232 * represented as the Base64URL encoding of the value's big 1233 * endian representation. May be {@code null}. 1234 * @param oth The other primes information, should they exist, 1235 * {@code null} or an empty list if not specified. 1236 * @param use The key use, {@code null} if not specified or if the key 1237 * is intended for signing as well as encryption. 1238 * @param ops The key operations, {@code null} if not specified. 1239 * @param alg The intended JOSE algorithm for the key, {@code null} if 1240 * not specified. 1241 * @param kid The key ID. {@code null} if not specified. 1242 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1243 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1244 * if not specified. 1245 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1246 * if not specified. 1247 * @param x5c The X.509 certificate chain, {@code null} if not 1248 * specified. 1249 */ 1250 @Deprecated 1251 public RSAKey(final Base64URL n, final Base64URL e, 1252 final Base64URL d, 1253 final Base64URL p, final Base64URL q, 1254 final Base64URL dp, final Base64URL dq, final Base64URL qi, 1255 final List<OtherPrimesInfo> oth, 1256 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1257 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c) { 1258 1259 this(n, e, d, p, q, dp, dq, qi, oth, null, use, ops, alg, kid, x5u, x5t, x5t256, x5c, null); 1260 } 1261 1262 1263 /** 1264 * Creates a new public / private RSA JSON Web Key (JWK) with the 1265 * specified parameters. The private RSA key can be specified by its 1266 * first representation, its second representation (see RFC 3447, 1267 * section 3.2), or by a PKCS#11 handle as {@link PrivateKey}. 1268 * 1269 * <p>A valid first private RSA key representation must specify the 1270 * {@code d} parameter. 1271 * 1272 * <p>A valid second private RSA key representation must specify all 1273 * required Chinese Remainder Theorem (CRT) parameters - {@code p}, 1274 * {@code q}, {@code dp}, {@code dq} and {@code qi}, else an 1275 * {@link java.lang.IllegalArgumentException} will be thrown. 1276 * 1277 * @param n The the modulus value for the public RSA key. It is 1278 * represented as the Base64URL encoding of value's big 1279 * endian representation. Must not be {@code null}. 1280 * @param e The exponent value for the public RSA key. It is 1281 * represented as the Base64URL encoding of value's big 1282 * endian representation. Must not be {@code null}. 1283 * @param d The private exponent. It is represented as the Base64URL 1284 * encoding of the value's big endian representation. May 1285 * be {@code null}. 1286 * @param p The first prime factor. It is represented as the 1287 * Base64URL encoding of the value's big endian 1288 * representation. May be {@code null}. 1289 * @param q The second prime factor. It is represented as the 1290 * Base64URL encoding of the value's big endian 1291 * representation. May be {@code null}. 1292 * @param dp The first factor Chinese Remainder Theorem exponent. It 1293 * is represented as the Base64URL encoding of the value's 1294 * big endian representation. May be {@code null}. 1295 * @param dq The second factor Chinese Remainder Theorem exponent. It 1296 * is represented as the Base64URL encoding of the value's 1297 * big endian representation. May be {@code null}. 1298 * @param qi The first Chinese Remainder Theorem coefficient. It is 1299 * represented as the Base64URL encoding of the value's big 1300 * endian representation. May be {@code null}. 1301 * @param oth The other primes information, should they exist, 1302 * {@code null} or an empty list if not specified. 1303 * @param use The key use, {@code null} if not specified or if the key 1304 * is intended for signing as well as encryption. 1305 * @param ops The key operations, {@code null} if not specified. 1306 * @param alg The intended JOSE algorithm for the key, {@code null} if 1307 * not specified. 1308 * @param kid The key ID. {@code null} if not specified. 1309 * @param x5u The X.509 certificate URL, {@code null} if not specified. 1310 * @param x5t The X.509 certificate SHA-1 thumbprint, {@code null} 1311 * if not specified. 1312 * @param x5t256 The X.509 certificate SHA-256 thumbprint, {@code null} 1313 * if not specified. 1314 * @param x5c The X.509 certificate chain, {@code null} if not 1315 * specified. 1316 * @param ks Reference to the underlying key store, {@code null} if 1317 * not specified. 1318 */ 1319 public RSAKey(final Base64URL n, final Base64URL e, 1320 final Base64URL d, 1321 final Base64URL p, final Base64URL q, 1322 final Base64URL dp, final Base64URL dq, final Base64URL qi, 1323 final List<OtherPrimesInfo> oth, 1324 final PrivateKey prv, 1325 final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid, 1326 final URI x5u, final Base64URL x5t, final Base64URL x5t256, final List<Base64> x5c, 1327 final KeyStore ks) { 1328 1329 super(KeyType.RSA, use, ops, alg, kid, x5u, x5t, x5t256, x5c, ks); 1330 1331 1332 // Ensure the public params are defined 1333 1334 if (n == null) { 1335 throw new IllegalArgumentException("The modulus value must not be null"); 1336 } 1337 1338 this.n = n; 1339 1340 1341 if (e == null) { 1342 throw new IllegalArgumentException("The public exponent value must not be null"); 1343 } 1344 1345 this.e = e; 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 LinkedHashMap<String,?> getRequiredParams() { 1915 1916 // Put mandatory params in sorted order 1917 LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>(); 1918 requiredParams.put("e", e.toString()); 1919 requiredParams.put("kty", getKeyType().getValue()); 1920 requiredParams.put("n", n.toString()); 1921 return requiredParams; 1922 } 1923 1924 1925 @Override 1926 public boolean isPrivate() { 1927 1928 // Check if 1st or 2nd form params are specified, or PKCS#11 handle 1929 return d != null || p != null || privateKey != null; 1930 } 1931 1932 1933 @Override 1934 public int size() { 1935 1936 return ByteUtils.bitLength(n.decode()); 1937 } 1938 1939 1940 /** 1941 * Returns a copy of this RSA JWK with any private values removed. 1942 * 1943 * @return The copied public RSA JWK. 1944 */ 1945 @Override 1946 public RSAKey toPublicJWK() { 1947 1948 return new RSAKey( 1949 getModulus(), getPublicExponent(), 1950 getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(), 1951 getX509CertURL(), getX509CertThumbprint(), getX509CertSHA256Thumbprint(), getX509CertChain(), 1952 getKeyStore()); 1953 } 1954 1955 1956 @Override 1957 public JSONObject toJSONObject() { 1958 1959 JSONObject o = super.toJSONObject(); 1960 1961 // Append public RSA key specific attributes 1962 o.put("n", n.toString()); 1963 o.put("e", e.toString()); 1964 if (d != null) { 1965 o.put("d", d.toString()); 1966 } 1967 if (p != null) { 1968 o.put("p", p.toString()); 1969 } 1970 if (q != null) { 1971 o.put("q", q.toString()); 1972 } 1973 if (dp != null) { 1974 o.put("dp", dp.toString()); 1975 } 1976 if (dq != null) { 1977 o.put("dq", dq.toString()); 1978 } 1979 if (qi != null) { 1980 o.put("qi", qi.toString()); 1981 } 1982 if (oth != null && !oth.isEmpty()) { 1983 1984 JSONArray a = new JSONArray(); 1985 1986 for (OtherPrimesInfo other : oth) { 1987 1988 JSONObject oo = new JSONObject(); 1989 oo.put("r", other.r.toString()); 1990 oo.put("d", other.d.toString()); 1991 oo.put("t", other.t.toString()); 1992 1993 a.add(oo); 1994 } 1995 1996 o.put("oth", a); 1997 } 1998 1999 return o; 2000 } 2001 2002 2003 /** 2004 * Parses a public / private RSA JWK from the specified JSON object 2005 * string representation. 2006 * 2007 * @param s The JSON object string to parse. Must not be {@code null}. 2008 * 2009 * @return The public / private RSA JWK. 2010 * 2011 * @throws ParseException If the string couldn't be parsed to an RSA 2012 * JWK. 2013 */ 2014 public static RSAKey parse(final String s) 2015 throws ParseException { 2016 2017 return parse(JSONObjectUtils.parse(s)); 2018 } 2019 2020 2021 /** 2022 * Parses a public / private RSA JWK from the specified JSON object 2023 * representation. 2024 * 2025 * @param jsonObject The JSON object to parse. Must not be 2026 * {@code null}. 2027 * 2028 * @return The public / private RSA Key. 2029 * 2030 * @throws ParseException If the JSON object couldn't be parsed to an 2031 * RSA JWK. 2032 */ 2033 public static RSAKey parse(final JSONObject jsonObject) 2034 throws ParseException { 2035 2036 // Parse the mandatory public key parameters first 2037 Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n")); 2038 Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e")); 2039 2040 // Check key type 2041 KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty")); 2042 if (kty != KeyType.RSA) { 2043 throw new ParseException("The key type \"kty\" must be RSA", 0); 2044 } 2045 2046 // Parse the optional private key parameters 2047 2048 // 1st private representation 2049 Base64URL d = null; 2050 if (jsonObject.containsKey("d")) { 2051 d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d")); 2052 } 2053 2054 // 2nd private (CRT) representation 2055 Base64URL p = null; 2056 if (jsonObject.containsKey("p")) { 2057 p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p")); 2058 } 2059 Base64URL q = null; 2060 if (jsonObject.containsKey("q")) { 2061 q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q")); 2062 } 2063 Base64URL dp = null; 2064 if (jsonObject.containsKey("dp")) { 2065 dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp")); 2066 } 2067 Base64URL dq= null; 2068 if (jsonObject.containsKey("dq")) { 2069 dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq")); 2070 } 2071 Base64URL qi = null; 2072 if (jsonObject.containsKey("qi")) { 2073 qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi")); 2074 } 2075 2076 List<OtherPrimesInfo> oth = null; 2077 if (jsonObject.containsKey("oth")) { 2078 2079 JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth"); 2080 oth = new ArrayList<>(arr.size()); 2081 2082 for (Object o : arr) { 2083 2084 if (o instanceof JSONObject) { 2085 JSONObject otherJson = (JSONObject)o; 2086 2087 Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r")); 2088 Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq")); 2089 Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t")); 2090 2091 OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t); 2092 oth.add(prime); 2093 } 2094 } 2095 } 2096 2097 try { 2098 return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, null, 2099 JWKMetadata.parseKeyUse(jsonObject), 2100 JWKMetadata.parseKeyOperations(jsonObject), 2101 JWKMetadata.parseAlgorithm(jsonObject), 2102 JWKMetadata.parseKeyID(jsonObject), 2103 JWKMetadata.parseX509CertURL(jsonObject), 2104 JWKMetadata.parseX509CertThumbprint(jsonObject), 2105 JWKMetadata.parseX509CertSHA256Thumbprint(jsonObject), 2106 JWKMetadata.parseX509CertChain(jsonObject), 2107 null); 2108 2109 } catch (IllegalArgumentException ex) { 2110 2111 // Inconsistent 2nd spec, conflicting 'use' and 'key_ops' 2112 throw new ParseException(ex.getMessage(), 0); 2113 } 2114 } 2115 2116 2117 /** 2118 * Parses a public RSA JWK from the specified X.509 certificate. 2119 * 2120 * <p><strong>Important:</strong> The X.509 certificate is not 2121 * validated! 2122 * 2123 * <p>Sets the following JWK parameters: 2124 * 2125 * <ul> 2126 * <li>The JWK use inferred by {@link KeyUse#from}. 2127 * <li>The JWK ID from the X.509 serial number (in base 10). 2128 * <li>The JWK X.509 certificate chain (this certificate only). 2129 * <li>The JWK X.509 certificate SHA-256 thumbprint. 2130 * </ul> 2131 * 2132 * @param cert The X.509 certificate. Must not be {@code null}. 2133 * 2134 * @return The public RSA key. 2135 * 2136 * @throws JOSEException If parsing failed. 2137 */ 2138 public static RSAKey parse(final X509Certificate cert) 2139 throws JOSEException { 2140 2141 if (! (cert.getPublicKey() instanceof RSAPublicKey)) { 2142 throw new JOSEException("The public key of the X.509 certificate is not RSA"); 2143 } 2144 2145 RSAPublicKey publicKey = (RSAPublicKey)cert.getPublicKey(); 2146 2147 try { 2148 MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); 2149 2150 return new RSAKey.Builder(publicKey) 2151 .keyUse(KeyUse.from(cert)) 2152 .keyID(cert.getSerialNumber().toString(10)) 2153 .x509CertChain(Collections.singletonList(Base64.encode(cert.getEncoded()))) 2154 .x509CertSHA256Thumbprint(Base64URL.encode(sha256.digest(cert.getEncoded()))) 2155 .build(); 2156 } catch (NoSuchAlgorithmException e) { 2157 throw new JOSEException("Couldn't encode x5t parameter: " + e.getMessage(), e); 2158 } catch (CertificateEncodingException e) { 2159 throw new JOSEException("Couldn't encode x5c parameter: " + e.getMessage(), e); 2160 } 2161 } 2162 2163 2164 /** 2165 * Loads a public / private RSA JWK from the specified JCA key store. 2166 * 2167 * <p><strong>Important:</strong> The X.509 certificate is not 2168 * validated! 2169 * 2170 * @param keyStore The key store. Must not be {@code null}. 2171 * @param alias The alias. Must not be {@code null}. 2172 * @param pin The pin to unlock the private key if any, empty or 2173 * {@code null} if not required. 2174 * 2175 * @return The public / private RSA key, {@code null} if no key with 2176 * the specified alias was found. 2177 * 2178 * @throws KeyStoreException On a key store exception. 2179 * @throws JOSEException If RSA key loading failed. 2180 */ 2181 public static RSAKey load(final KeyStore keyStore, 2182 final String alias, 2183 final char[] pin) 2184 throws KeyStoreException, JOSEException { 2185 2186 java.security.cert.Certificate cert = keyStore.getCertificate(alias); 2187 2188 if (cert == null || ! (cert instanceof X509Certificate)) { 2189 return null; 2190 } 2191 2192 X509Certificate x509Cert = (X509Certificate)cert; 2193 2194 if (! (x509Cert.getPublicKey() instanceof RSAPublicKey)) { 2195 throw new JOSEException("Couldn't load RSA JWK: The key algorithm is not RSA"); 2196 } 2197 2198 RSAKey rsaJWK = RSAKey.parse(x509Cert); 2199 2200 // Let kid=alias 2201 rsaJWK = new RSAKey.Builder(rsaJWK).keyID(alias).keyStore(keyStore).build(); 2202 2203 // Check for private counterpart 2204 Key key; 2205 try { 2206 key = keyStore.getKey(alias, pin); 2207 } catch (UnrecoverableKeyException | NoSuchAlgorithmException e) { 2208 throw new JOSEException("Couldn't retrieve private RSA key (bad pin?): " + e.getMessage(), e); 2209 } 2210 2211 if (key instanceof RSAPrivateKey) { 2212 // Simple file based key store 2213 return new RSAKey.Builder(rsaJWK) 2214 .privateKey((RSAPrivateKey)key) 2215 .build(); 2216 } else if (key instanceof PrivateKey && "RSA".equalsIgnoreCase(key.getAlgorithm())) { 2217 // PKCS#11 store 2218 return new RSAKey.Builder(rsaJWK) 2219 .privateKey((PrivateKey)key) 2220 .build(); 2221 } else { 2222 return rsaJWK; 2223 } 2224 } 2225}