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