001package com.nimbusds.jose.jwk;
002
003
004import java.io.Serializable;
005import java.net.URI;
006import java.math.BigInteger;
007import java.security.*;
008import java.security.interfaces.RSAMultiPrimePrivateCrtKey;
009import java.security.interfaces.RSAPrivateCrtKey;
010import java.security.interfaces.RSAPrivateKey;
011import java.security.interfaces.RSAPublicKey;
012import java.security.spec.InvalidKeySpecException;
013import java.security.spec.RSAMultiPrimePrivateCrtKeySpec;
014import java.security.spec.RSAOtherPrimeInfo;
015import java.security.spec.RSAPrivateCrtKeySpec;
016import java.security.spec.RSAPrivateKeySpec;
017import java.security.spec.RSAPublicKeySpec;
018import java.text.ParseException;
019import java.util.*;
020
021import com.nimbusds.jose.util.ByteUtils;
022import net.jcip.annotations.Immutable;
023
024import net.minidev.json.JSONArray;
025import net.minidev.json.JSONObject;
026
027import com.nimbusds.jose.Algorithm;
028import com.nimbusds.jose.JOSEException;
029import com.nimbusds.jose.util.Base64;
030import com.nimbusds.jose.util.Base64URL;
031import com.nimbusds.jose.util.JSONObjectUtils;
032
033
034/**
035 * Public and private {@link KeyType#RSA RSA} JSON Web Key (JWK). This class is
036 * immutable.
037 *
038 * <p>Provides RSA JWK import from / export to the following standard Java 
039 * interfaces and classes:
040 *
041 * <ul>
042 *     <li>{@code java.security.interfaces.RSAPublicKey}
043 *     <li>{@code java.security.interfaces.RSAPrivateKey}
044 *         <ul>
045 *             <li>{@code java.security.interfaces.RSAPrivateCrtKey}
046 *             <li>{@code java.security.interfaces.RSAMultiPrimePrivateCrtKey}
047 *         </ul>
048 *     <li>{@code java.security.KeyPair}
049 * </ul>
050 *
051 * <p>Example JSON object representation of a public RSA JWK:
052 *
053 * <pre>
054 * { 
055 *   "kty" : "RSA",
056 *   "n"   : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
057 *            4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
058 *            tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
059 *            QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
060 *            SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
061 *            w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
062 *   "e"   : "AQAB",
063 *   "alg" : "RS256",
064 *   "kid" : "2011-04-29"
065 * }
066 * </pre>
067 *
068 * <p>Example JSON object representation of a public and private RSA JWK (with 
069 * both the first and the second private key representations):
070 *
071 * <pre>
072 * { 
073 *   "kty" : "RSA",
074 *   "n"   : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
075 *            4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
076 *            tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
077 *            QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
078 *            SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
079 *            w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
080 *   "e"   : "AQAB",
081 *   "d"   : "X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9
082 *            M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqij
083 *            wp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d
084 *            _cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBz
085 *            nbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFz
086 *            me1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
087 *   "p"   : "83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPV
088 *            nwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqV
089 *            WlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
090 *   "q"   : "3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyum
091 *            qjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgx
092 *            kIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
093 *   "dp"  : "G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oim
094 *            YwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_Nmtu
095 *            YZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
096 *   "dq"  : "s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUU
097 *            vMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9
098 *            GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
099 *   "qi"  : "GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzg
100 *            UIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rx
101 *            yR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
102 *   "alg" : "RS256",
103 *   "kid" : "2011-04-29"
104 * }
105 * </pre>
106 *
107 * <p>See RFC 3447.
108 *
109 * <p>See http://en.wikipedia.org/wiki/RSA_%28algorithm%29
110 *
111 * @author Vladimir Dzhuvinov
112 * @author Justin Richer
113 * @author Cedric Staub
114 * @version 2016-07-03
115 */
116@Immutable
117public final class RSAKey extends JWK implements AssymetricJWK {
118
119
120        private static final long serialVersionUID = 1L;
121
122
123        /**
124         * Other Primes Info, represents the private {@code oth} parameter of a
125         * RSA JWK. This class is immutable.
126         */
127        @Immutable
128        public static class OtherPrimesInfo implements Serializable {
129
130
131                private static final long serialVersionUID = 1L;
132
133
134                 /**
135                  * The prime factor.
136                  */
137                private final Base64URL r;
138
139                
140                /**
141                 * The factor Chinese Remainder Theorem (CRT) exponent.
142                 */
143                private final Base64URL d;
144        
145
146                /**
147                 * The factor Chinese Remainder Theorem (CRT) coefficient.
148                 */
149                private final Base64URL t;
150
151
152                /**
153                 * Creates a new JWK Other Primes Info with the specified 
154                 * parameters.
155                 *
156                 * @param r The prime factor. Must not be {@code null}.
157                 * @param d The factor Chinese Remainder Theorem (CRT) 
158                 *          exponent. Must not be {@code null}.
159                 * @param t The factor Chinese Remainder Theorem (CRT) 
160                 *          coefficient. Must not be {@code null}.
161                 */
162                public OtherPrimesInfo(final Base64URL r, final Base64URL d, final Base64URL t) {
163
164                        if (r == null) {
165
166                                throw new IllegalArgumentException("The prime factor must not be null");
167                        }
168
169                        this.r = r;
170
171                        if (d == null) {
172
173                                throw new IllegalArgumentException("The factor CRT exponent must not be null");
174                        }
175
176                        this.d = d;
177
178                        if (t == null) {
179
180                                throw new IllegalArgumentException("The factor CRT coefficient must not be null");
181                        }
182                        
183                        this.t = t;
184                }
185
186
187                /**
188                 * Creates a new JWK Other Primes Info from the specified
189                 * {@code java.security.spec.RSAOtherPrimeInfo} instance.
190                 *
191                 * @param oth The RSA Other Primes Info instance. Must not be 
192                 *            {@code null}.
193                 */
194                public OtherPrimesInfo(final RSAOtherPrimeInfo oth) {
195
196                        r = Base64URL.encode(oth.getPrime());
197                        d = Base64URL.encode(oth.getExponent());
198                        t = Base64URL.encode(oth.getCrtCoefficient());
199                }
200       
201        
202                /**
203                 * Gets the prime factor ({@code r}).
204                 *
205                 * @return The prime factor.
206                 */
207                public Base64URL getPrimeFactor() {
208
209                        return r;
210                }
211
212
213                /**
214                 * Gets factor Chinese Remainder Theorem (CRT) exponent
215                 * ({@code d}).
216                 *
217                 * @return The factor Chinese Remainder Theorem (CRT) exponent.
218                 */
219                public Base64URL getFactorCRTExponent() {
220
221                        return d;
222                }
223
224
225                /**
226                 * The factor Chinese Remainder Theorem (CRT) coefficient
227                 * ({@code t}).
228                 *
229                 * @return The factor Chinese Remainder Theorem (CRT) 
230                 *         coefficient.
231                 */
232                public Base64URL getFactorCRTCoefficient() {
233
234                        return t;
235                }
236
237
238                /**
239                 * Converts the specified array of 
240                 * {@code java.security.spec.RSAOtherPrimeInfo} instances to a
241                 * list of JWK Other Prime Infos.
242                 *
243                 * @param othArray Array of RSA Other Primes Info instances. 
244                 *                 May be be {@code null}.
245                 *
246                 * @return The corresponding list of JWK Other Prime Infos, or
247                 *         empty list of the array was {@code null}.
248                 */
249                public static List<OtherPrimesInfo> toList(final RSAOtherPrimeInfo[] othArray) {
250
251                        List<OtherPrimesInfo> list = new ArrayList<>();
252
253                        if (othArray == null) {
254
255                                // Return empty list
256                                return list;
257                        }
258
259                        for (RSAOtherPrimeInfo oth: othArray) {
260
261                                list.add(new OtherPrimesInfo(oth));
262                        }
263
264                        return list;
265                }
266        }
267
268
269        /**
270         * Builder for constructing RSA JWKs.
271         *
272         * <p>Example usage:
273         *
274         * <pre>
275         * RSAKey key = new RSAKey.Builder(n, e).
276         *              privateExponent(d).
277         *              algorithm(JWSAlgorithm.RS512).
278         *              keyID("456").
279         *              build();
280         * </pre>
281         */
282        public static class Builder {
283
284
285                // Public RSA params
286
287                /**
288                 * The modulus value for the RSA key.
289                 */
290                private final Base64URL n;
291
292
293                /**
294                 * The public exponent of the RSA key.
295                 */
296                private final Base64URL e;
297
298
299                // Private RSA params, 1st representation       
300
301                /**
302                 * The private exponent of the RSA key.
303                 */
304                private Base64URL d;
305
306                
307                // Private RSA params, 2nd representation
308
309                /**
310                 * The first prime factor of the private RSA key.
311                 */
312                private Base64URL p;
313
314                
315                /**
316                 * The second prime factor of the private RSA key.
317                 */
318                private Base64URL q;
319
320                
321                /**
322                 * The first factor Chinese Remainder Theorem exponent of the 
323                 * private RSA key.
324                 */
325                private Base64URL dp;
326
327                
328                /**
329                 * The second factor Chinese Remainder Theorem exponent of the
330                 * private RSA key.
331                 */
332                private Base64URL dq;
333
334                
335                /**
336                 * The first Chinese Remainder Theorem coefficient of the private RSA
337                 * key.
338                 */
339                private Base64URL qi;
340
341                
342                /**
343                 * The other primes information of the private RSA key, should
344                 * they exist. When only two primes have been used (the normal
345                 * case), this parameter MUST be omitted. When three or more 
346                 * primes have been used, the number of array elements MUST be 
347                 * the number of primes used minus two.
348                 */
349                private List<OtherPrimesInfo> oth;
350
351
352                /**
353                 * The key use, optional.
354                 */
355                private KeyUse use;
356
357
358                /**
359                 * The key operations, optional.
360                 */
361                private Set<KeyOperation> ops;
362
363
364                /**
365                 * The intended JOSE algorithm for the key, optional.
366                 */
367                private Algorithm alg;
368
369
370                /**
371                 * The key ID, optional.
372                 */
373                private String kid;
374
375
376                /**
377                 * X.509 certificate URL, optional.
378                 */
379                private URI x5u;
380
381
382                /**
383                 * X.509 certificate thumbprint, optional.
384                 */
385                private Base64URL x5t;
386
387
388                /**
389                 * The X.509 certificate chain, optional.
390                 */
391                private List<Base64> x5c;
392
393
394                /**
395                 * Creates a new RSA JWK builder.
396                 *
397                 * @param n The the modulus value for the public RSA key. It is 
398                 *          represented as the Base64URL encoding of value's 
399                 *          big endian representation. Must not be 
400                 *          {@code null}.
401                 * @param e The exponent value for the public RSA key. It is 
402                 *          represented as the Base64URL encoding of value's 
403                 *          big endian representation. Must not be 
404                 *          {@code null}.
405                 */
406                public Builder(final Base64URL n, final Base64URL e) {
407
408                        // Ensure the public params are defined
409
410                        if (n == null) {
411                                throw new IllegalArgumentException("The modulus value must not be null");
412                        }
413
414                        this.n = n;
415
416
417                        if (e == null) {
418                                throw new IllegalArgumentException("The public exponent value must not be null");
419                        }
420
421                        this.e = e;
422                }
423
424
425                /**
426                 * Creates a new RSA JWK builder.
427                 * 
428                 * @param pub The public RSA key to represent. Must not be 
429                 *            {@code null}.
430                 */
431                public Builder(final RSAPublicKey pub) {
432
433                        n = Base64URL.encode(pub.getModulus());
434                        e = Base64URL.encode(pub.getPublicExponent());
435                }
436
437
438                /**
439                 * Sets the private exponent ({@code d}) of the RSA key.
440                 *
441                 * @param d The private RSA key exponent. It is represented as 
442                 *          the Base64URL encoding of the value's big endian 
443                 *          representation. {@code null} if not specified (for 
444                 *          a public key or a private key using the second 
445                 *          representation only).
446                 *
447                 * @return This builder.
448                 */
449                public Builder privateExponent(final Base64URL d) {
450
451                        this.d = d;
452                        return this;
453                }
454
455
456                /**
457                 * Sets the private RSA key, using the first representation.
458                 * 
459                 * @param priv The private RSA key, used to obtain the private
460                 *             exponent ({@code d}). Must not be {@code null}.
461                 *
462                 * @return This builder.
463                 */
464                public Builder privateKey(final RSAPrivateKey priv) {
465
466                        if (priv instanceof RSAPrivateCrtKey) {
467                                return this.privateKey((RSAPrivateCrtKey) priv);
468                        } else if (priv instanceof RSAMultiPrimePrivateCrtKey) {
469                                return this.privateKey((RSAMultiPrimePrivateCrtKey) priv);
470                        } else {
471                                this.d = Base64URL.encode(priv.getPrivateExponent());
472                                return this;
473                        }
474                }
475
476
477                /**
478                 * Sets the first prime factor ({@code p}) of the private RSA
479                 * key. 
480                 *
481                 * @param p The RSA first prime factor. It is represented as 
482                 *          the Base64URL encoding of the value's big endian 
483                 *          representation. {@code null} if not specified (for 
484                 *          a public key or a private key using the first 
485                 *          representation only).
486                 *
487                 * @return This builder.
488                 */
489                public Builder firstPrimeFactor(final Base64URL p) {
490
491                        this.p = p;
492                        return this;
493                }
494
495
496                /**
497                 * Sets the second prime factor ({@code q}) of the private RSA 
498                 * key.
499                 *
500                 * @param q The RSA second prime factor. It is represented as 
501                 *          the Base64URL encoding of the value's big endian 
502                 *          representation. {@code null} if not specified (for 
503                 *          a public key or a private key using the first 
504                 *          representation only).
505                 *
506                 * @return This builder.
507                 */
508                public Builder secondPrimeFactor(final Base64URL q) {
509
510                        this.q = q;
511                        return this;
512                }
513
514
515                /**
516                 * Sets the first factor Chinese Remainder Theorem (CRT) 
517                 * exponent ({@code dp}) of the private RSA key.
518                 *
519                 * @param dp The RSA first factor CRT exponent. It is 
520                 *           represented as the Base64URL encoding of the 
521                 *           value's big endian representation. {@code null} 
522                 *           if not specified (for a public key or a private
523                 *           key using the first representation only).
524                 *
525                 * @return This builder.
526                 */
527                public Builder firstFactorCRTExponent(final Base64URL dp) {
528
529                        this.dp = dp;
530                        return this;
531                }
532
533
534                /**
535                 * Sets the second factor Chinese Remainder Theorem (CRT) 
536                 * exponent ({@code dq}) of the private RSA key.
537                 *
538                 * @param dq The RSA second factor CRT exponent. It is 
539                 *           represented as the Base64URL encoding of the 
540                 *           value's big endian representation. {@code null} if 
541                 *           not specified (for a public key or a private key 
542                 *           using the first representation only).
543                 *
544                 * @return This builder.
545                 */
546                public Builder secondFactorCRTExponent(final Base64URL dq) {
547
548                        this.dq = dq;
549                        return this;
550                }
551
552
553                /**
554                 * Sets the first Chinese Remainder Theorem (CRT) coefficient
555                 * ({@code qi})} of the private RSA key.
556                 *
557                 * @param qi The RSA first CRT coefficient. It is represented 
558                 *           as the Base64URL encoding of the value's big 
559                 *           endian representation. {@code null} if not 
560                 *           specified (for a public key or a private key using 
561                 *           the first representation only).
562                 *
563                 * @return This builder.
564                 */
565                public Builder firstCRTCoefficient(final Base64URL qi) {
566
567                        this.qi = qi;
568                        return this;
569                }
570
571
572                /**
573                 * Sets the other primes information ({@code oth}) for the 
574                 * private RSA key, should they exist.
575                 *
576                 * @param oth The RSA other primes information, {@code null} or 
577                 *            empty list if not specified.
578                 *
579                 * @return This builder.
580                 */
581                public Builder otherPrimes(final List<OtherPrimesInfo> oth) {
582
583                        this.oth = oth;
584                        return this;
585                }
586
587
588                /**
589                 * Sets the private RSA key, using the second representation 
590                 * (see RFC 3447, section 3.2).
591                 * 
592                 * @param priv The private RSA key, used to obtain the private
593                 *             exponent ({@code d}), the first prime factor
594                 *             ({@code p}), the second prime factor 
595                 *             ({@code q}), the first factor CRT exponent 
596                 *             ({@code dp}), the second factor CRT exponent
597                 *             ({@code dq}) and the first CRT coefficient 
598                 *             ({@code qi}). Must not be {@code null}.
599                 *
600                 * @return This builder.
601                 */
602                public Builder privateKey(final RSAPrivateCrtKey priv) {
603
604                        d = Base64URL.encode(priv.getPrivateExponent());
605                        p = Base64URL.encode(priv.getPrimeP());
606                        q = Base64URL.encode(priv.getPrimeQ());
607                        dp = Base64URL.encode(priv.getPrimeExponentP());
608                        dq = Base64URL.encode(priv.getPrimeExponentQ());
609                        qi = Base64URL.encode(priv.getCrtCoefficient());
610
611                        return this;
612                }
613
614
615                /**
616                 * Sets the private RSA key, using the second representation, 
617                 * with optional other primes info (see RFC 3447, section 3.2).
618                 * 
619                 * @param priv The private RSA key, used to obtain the private
620                 *             exponent ({@code d}), the first prime factor
621                 *             ({@code p}), the second prime factor 
622                 *             ({@code q}), the first factor CRT exponent 
623                 *             ({@code dp}), the second factor CRT exponent
624                 *             ({@code dq}), the first CRT coefficient 
625                 *             ({@code qi}) and the other primes info
626                 *             ({@code oth}). Must not be {@code null}.
627                 *
628                 * @return This builder.
629                 */
630                public Builder privateKey(final RSAMultiPrimePrivateCrtKey priv) {
631                        
632                        d = Base64URL.encode(priv.getPrivateExponent());
633                        p = Base64URL.encode(priv.getPrimeP());
634                        q = Base64URL.encode(priv.getPrimeQ());
635                        dp = Base64URL.encode(priv.getPrimeExponentP());
636                        dq = Base64URL.encode(priv.getPrimeExponentQ());
637                        qi = Base64URL.encode(priv.getCrtCoefficient());
638                        oth = OtherPrimesInfo.toList(priv.getOtherPrimeInfo());
639
640                        return this;
641                }
642
643
644                /**
645                 * Sets the use ({@code use}) of the JWK.
646                 *
647                 * @param use The key use, {@code null} if not specified or if
648                 *            the key is intended for signing as well as
649                 *            encryption.
650                 *
651                 * @return This builder.
652                 */
653                public Builder keyUse(final KeyUse use) {
654
655                        this.use = use;
656                        return this;
657                }
658
659
660                /**
661                 * Sets the operations ({@code key_ops}) of the JWK (for a
662                 * non-public key).
663                 *
664                 * @param ops The key operations, {@code null} if not
665                 *            specified.
666                 *
667                 * @return This builder.
668                 */
669                public Builder keyOperations(final Set<KeyOperation> ops) {
670
671                        this.ops = ops;
672                        return this;
673                }
674
675
676                /**
677                 * Sets the intended JOSE algorithm ({@code alg}) for the JWK.
678                 *
679                 * @param alg The intended JOSE algorithm, {@code null} if not
680                 *            specified.
681                 *
682                 * @return This builder.
683                 */
684                public Builder algorithm(final Algorithm alg) {
685
686                        this.alg = alg;
687                        return this;
688                }
689
690                /**
691                 * Sets the ID ({@code kid}) of the JWK. The key ID can be used
692                 * to match a specific key. This can be used, for instance, to
693                 * choose a key within a {@link JWKSet} during key rollover.
694                 * The key ID may also correspond to a JWS/JWE {@code kid}
695                 * header parameter value.
696                 *
697                 * @param kid The key ID, {@code null} if not specified.
698                 *
699                 * @return This builder.
700                 */
701                public Builder keyID(final String kid) {
702
703                        this.kid = kid;
704                        return this;
705                }
706
707
708                /**
709                 * Sets the ID ({@code kid}) of the JWK to its SHA-256 JWK
710                 * thumbprint (RFC 7638). The key ID can be used to match a
711                 * specific key. This can be used, for instance, to choose a
712                 * key within a {@link JWKSet} during key rollover. The key ID
713                 * may also correspond to a JWS/JWE {@code kid} header
714                 * parameter value.
715                 *
716                 * @return This builder.
717                 *
718                 * @throws JOSEException If the SHA-256 hash algorithm is not
719                 *                       supported.
720                 */
721                public Builder keyIDFromThumbprint()
722                        throws JOSEException {
723
724                        return keyIDFromThumbprint("SHA-256");
725                }
726
727
728                /**
729                 * Sets the ID ({@code kid}) of the JWK to its JWK thumbprint
730                 * (RFC 7638). The key ID can be used to match a specific key.
731                 * This can be used, for instance, to choose a key within a
732                 * {@link JWKSet} during key rollover. The key ID may also
733                 * correspond to a JWS/JWE {@code kid} header parameter value.
734                 *
735                 * @param hashAlg The hash algorithm for the JWK thumbprint
736                 *                computation. Must not be {@code null}.
737                 *
738                 * @return This builder.
739                 *
740                 * @throws JOSEException If the hash algorithm is not
741                 *                       supported.
742                 */
743                public Builder keyIDFromThumbprint(final String hashAlg)
744                        throws JOSEException {
745
746                        // Put mandatory params in sorted order
747                        LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>();
748                        requiredParams.put("e", e.toString());
749                        requiredParams.put("kty", KeyType.RSA.getValue());
750                        requiredParams.put("n", n.toString());
751                        this.kid = ThumbprintUtils.compute(hashAlg, requiredParams).toString();
752                        return this;
753                }
754
755
756                /**
757                 * Sets the X.509 certificate URL ({@code x5u}) of the JWK.
758                 *
759                 * @param x5u The X.509 certificate URL, {@code null} if not
760                 *            specified.
761                 *
762                 * @return This builder.
763                 */
764                public Builder x509CertURL(final URI x5u) {
765
766                        this.x5u = x5u;
767                        return this;
768                }
769
770
771                /**
772                 * Sets the X.509 certificate thumbprint ({@code x5t}) of the
773                 * JWK.
774                 *
775                 * @param x5t The X.509 certificate thumbprint, {@code null} if
776                 *            not specified.
777                 *
778                 * @return This builder.
779                 */
780                public Builder x509CertThumbprint(final Base64URL x5t) {
781
782                        this.x5t = x5t;
783                        return this;
784                }
785
786                /**
787                 * Sets the X.509 certificate chain ({@code x5c}) of the JWK.
788                 *
789                 * @param x5c The X.509 certificate chain as a unmodifiable
790                 *            list, {@code null} if not specified.
791                 *
792                 * @return This builder.
793                 */
794                public Builder x509CertChain(final List<Base64> x5c) {
795
796                        this.x5c = x5c;
797                        return this;
798                }
799
800                /**
801                 * Builds a new RSA JWK.
802                 *
803                 * @return The RSA JWK.
804                 *
805                 * @throws IllegalStateException If the JWK parameters were
806                 *                               inconsistently specified.
807                 */
808                public RSAKey build() {
809
810                        try {
811                                // The full constructor
812                                return new RSAKey(n, e, d, p, q, dp, dq, qi, oth,
813                                                  use, ops, alg, kid, x5u, x5t, x5c);
814
815                        } catch (IllegalArgumentException e) {
816
817                                throw new IllegalStateException(e.getMessage(), e);
818                        }
819                }
820        }
821
822
823        // Public RSA params
824
825        /**
826         * The modulus value of the RSA key.
827         */
828        private final Base64URL n;
829
830
831        /**
832         * The public exponent of the RSA key.
833         */
834        private final Base64URL e;
835
836
837        // Private RSA params, 1st representation       
838
839        /**
840         * The private exponent of the RSA key.
841         */
842        private final Base64URL d;
843
844        
845        // Private RSA params, 2nd representation
846
847        /**
848         * The first prime factor of the private RSA key.
849         */
850        private final Base64URL p;
851
852        
853        /**
854         * The second prime factor of the private RSA key.
855         */
856        private final Base64URL q;
857
858        
859        /**
860         * The first factor Chinese Remainder Theorem exponent of the private 
861         * RSA key.
862         */
863        private final Base64URL dp;
864
865        
866        /**
867         * The second factor Chinese Remainder Theorem exponent of the private
868         * RSA key.
869         */
870        private final Base64URL dq;
871
872        
873        /**
874         * The first Chinese Remainder Theorem coefficient of the private RSA
875         * key.
876         */
877        private final Base64URL qi;
878
879        
880        /**
881         * The other primes information of the private RSA key, should they
882         * exist. When only two primes have been used (the normal case), this 
883         * parameter MUST be omitted. When three or more primes have been used,
884         * the number of array elements MUST be the number of primes used minus
885         * two.
886         */
887        private final List<OtherPrimesInfo> oth;
888
889
890        /**
891         * Creates a new public RSA JSON Web Key (JWK) with the specified 
892         * parameters.
893         *
894         * @param n   The the modulus value for the public RSA key. It is 
895         *            represented as the Base64URL encoding of value's big 
896         *            endian representation. Must not be {@code null}.
897         * @param e   The exponent value for the public RSA key. It is 
898         *            represented as the Base64URL encoding of value's big 
899         *            endian representation. Must not be {@code null}.
900         * @param use The key use, {@code null} if not specified or if the key
901         *            is intended for signing as well as encryption.
902         * @param ops The key operations, {@code null} if not specified.
903         * @param alg The intended JOSE algorithm for the key, {@code null} if
904         *            not specified.
905         * @param kid The key ID. {@code null} if not specified.
906         * @param x5u The X.509 certificate URL, {@code null} if not specified.
907         * @param x5t The X.509 certificate thumbprint, {@code null} if not
908         *            specified.
909         * @param x5c The X.509 certificate chain, {@code null} if not 
910         *            specified.
911         */
912        public RSAKey(final Base64URL n, final Base64URL e,
913                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
914                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
915
916                // Call the full constructor, all private key parameters are null
917                this(n, e, null, null, null, null, null, null, null, use, ops, alg, kid,
918                     x5u, x5t, x5c);
919        }
920
921
922        /**
923         * Creates a new public / private RSA JSON Web Key (JWK) with the 
924         * specified parameters. The private RSA key is specified by its first
925         * representation (see RFC 3447, section 3.2).
926         * 
927         * @param n   The the modulus value for the public RSA key. It is
928         *            represented as the Base64URL encoding of value's big 
929         *            endian representation. Must not be {@code null}.
930         * @param e   The exponent value for the public RSA key. It is 
931         *            represented as the Base64URL encoding of value's big 
932         *            endian representation. Must not be {@code null}.
933         * @param d   The private exponent. It is represented as the Base64URL 
934         *            encoding of the value's big endian representation. Must 
935         *            not be {@code null}.
936         * @param use The key use, {@code null} if not specified or if the key
937         *            is intended for signing as well as encryption.
938         * @param ops The key operations, {@code null} if not specified.
939         * @param alg The intended JOSE algorithm for the key, {@code null} if
940         *            not specified.
941         * @param kid The key ID. {@code null} if not specified.
942         * @param x5u The X.509 certificate URL, {@code null} if not specified.
943         * @param x5t The X.509 certificate thumbprint, {@code null} if not
944         *            specified.
945         * @param x5c The X.509 certificate chain, {@code null} if not 
946         *            specified.
947         */
948        public RSAKey(final Base64URL n, final Base64URL e, final Base64URL d,
949                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
950                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
951            
952                // Call the full constructor, the second private representation 
953                // parameters are all null
954                this(n, e, d, null, null, null, null, null, null, use, ops, alg, kid,
955                     x5u, x5t, x5c);
956
957                if (d == null) {
958                        throw new IllegalArgumentException("The private exponent must not be null");
959                }
960        }
961
962
963        /**
964         * Creates a new public / private RSA JSON Web Key (JWK) with the 
965         * specified parameters. The private RSA key is specified by its
966         * second representation (see RFC 3447, section 3.2).
967         * 
968         * @param n   The the modulus value for the public RSA key. It is
969         *            represented as the Base64URL encoding of value's big 
970         *            endian representation. Must not be {@code null}.
971         * @param e   The exponent value for the public RSA key. It is 
972         *            represented as the Base64URL encoding of value's big 
973         *            endian representation. Must not be {@code null}.
974         * @param p   The first prime factor. It is represented as the 
975         *            Base64URL encoding of the value's big endian 
976         *            representation. Must not be {@code null}.
977         * @param q   The second prime factor. It is represented as the 
978         *            Base64URL encoding of the value's big endian 
979         *            representation. Must not be {@code null}.
980         * @param dp  The first factor Chinese Remainder Theorem exponent. It 
981         *            is represented as the Base64URL encoding of the value's 
982         *            big endian representation. Must not be {@code null}.
983         * @param dq  The second factor Chinese Remainder Theorem exponent. It 
984         *            is represented as the Base64URL encoding of the value's 
985         *            big endian representation. Must not be {@code null}.
986         * @param qi  The first Chinese Remainder Theorem coefficient. It is 
987         *            represented as the Base64URL encoding of the value's big 
988         *            endian representation. Must not be {@code null}.
989         * @param oth The other primes information, should they exist,
990         *            {@code null} or an empty list if not specified.
991         * @param use The key use, {@code null} if not specified or if the key
992         *            is intended for signing as well as encryption.
993         * @param ops The key operations, {@code null} if not specified.
994         * @param alg The intended JOSE algorithm for the key, {@code null} if
995         *            not specified.
996         * @param kid The key ID. {@code null} if not specified.
997         * @param x5u The X.509 certificate URL, {@code null} if not specified.
998         * @param x5t The X.509 certificate thumbprint, {@code null} if not
999         *            specified.
1000         * @param x5c The X.509 certificate chain, {@code null} if not 
1001         *            specified.
1002         */
1003        public RSAKey(final Base64URL n, final Base64URL e, 
1004                      final Base64URL p, final Base64URL q, 
1005                      final Base64URL dp, final Base64URL dq, final Base64URL qi, 
1006                      final List<OtherPrimesInfo> oth,
1007                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1008                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1009            
1010                // Call the full constructor, the first private representation 
1011                // d param is null
1012                this(n, e, null, p, q, dp, dq, qi, oth, use, ops, alg, kid,
1013                     x5u, x5t, x5c);
1014
1015                if (p == null) {
1016                        throw new IllegalArgumentException("The first prime factor must not be null");
1017                }
1018
1019                if (q == null) {
1020                        throw new IllegalArgumentException("The second prime factor must not be null");
1021                }
1022
1023                if (dp == null) {
1024                        throw new IllegalArgumentException("The first factor CRT exponent must not be null");
1025                }
1026
1027                if (dq == null) {
1028                        throw new IllegalArgumentException("The second factor CRT exponent must not be null");
1029                }
1030
1031                if (qi == null) {
1032                        throw new IllegalArgumentException("The first CRT coefficient must not be null");
1033                }
1034        }
1035
1036
1037        /**
1038         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1039         * specified parameters. The private RSA key is specified by both its
1040         * first and second representations (see RFC 3447, section 3.2).
1041         *
1042         * <p>A valid first private RSA key representation must specify the
1043         * {@code d} parameter.
1044         *
1045         * <p>A valid second private RSA key representation must specify all 
1046         * required Chinese Remained Theorem (CRT) parameters - {@code p}, 
1047         * {@code q}, {@code dp}, {@code dq} and {@code qi}, else an
1048         * {@link java.lang.IllegalArgumentException} will be thrown.
1049         * 
1050         * @param n   The the modulus 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 e   The exponent value for the public RSA key. It is 
1054         *            represented as the Base64URL encoding of value's big 
1055         *            endian representation. Must not be {@code null}.
1056         * @param d   The private exponent. It is represented as the Base64URL 
1057         *            encoding of the value's big endian representation. May 
1058         *            be {@code null}.
1059         * @param p   The first prime factor. It is represented as the 
1060         *            Base64URL encoding of the value's big endian 
1061         *            representation. May be {@code null}.
1062         * @param q   The second prime factor. It is represented as the 
1063         *            Base64URL encoding of the value's big endian 
1064         *            representation. May be {@code null}.
1065         * @param dp  The first factor Chinese Remainder Theorem exponent. It 
1066         *            is represented as the Base64URL encoding of the value's 
1067         *            big endian representation. May be {@code null}.
1068         * @param dq  The second factor Chinese Remainder Theorem exponent. It 
1069         *            is represented as the Base64URL encoding of the value's 
1070         *            big endian representation. May be {@code null}.
1071         * @param qi  The first Chinese Remainder Theorem coefficient. It is 
1072         *            represented as the Base64URL encoding of the value's big 
1073         *            endian representation. May be {@code null}.
1074         * @param oth The other primes information, should they exist,
1075         *            {@code null} or an empty list if not specified.
1076         * @param use The key use, {@code null} if not specified or if the key
1077         *            is intended for signing as well as encryption.
1078         * @param ops The key operations, {@code null} if not specified.
1079         * @param alg The intended JOSE algorithm for the key, {@code null} if
1080         *            not specified.
1081         * @param kid The key ID. {@code null} if not specified.
1082         * @param x5u The X.509 certificate URL, {@code null} if not specified.
1083         * @param x5t The X.509 certificate thumbprint, {@code null} if not
1084         *            specified.
1085         * @param x5c The X.509 certificate chain, {@code null} if not 
1086         *            specified.
1087         */
1088        public RSAKey(final Base64URL n, final Base64URL e,
1089                      final Base64URL d, 
1090                      final Base64URL p, final Base64URL q, 
1091                      final Base64URL dp, final Base64URL dq, final Base64URL qi, 
1092                      final List<OtherPrimesInfo> oth,
1093                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1094                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1095            
1096                super(KeyType.RSA, use, ops, alg, kid, x5u, x5t, x5c);
1097
1098
1099                // Ensure the public params are defined
1100
1101                if (n == null) {
1102                        throw new IllegalArgumentException("The modulus value must not be null");
1103                }
1104
1105                this.n = n;
1106
1107
1108                if (e == null) {
1109                        throw new IllegalArgumentException("The public exponent value must not be null");
1110                }
1111
1112                this.e = e;
1113
1114
1115                // Private params, 1st representation
1116
1117                this.d = d;
1118
1119
1120                // Private params, 2nd representation, check for consistency
1121
1122                if (p != null && q != null && dp != null && dq != null && qi != null) {
1123
1124                        // CRT params fully specified
1125                        this.p = p;
1126                        this.q = q;
1127                        this.dp = dp;
1128                        this.dq = dq;
1129                        this.qi = qi;
1130
1131                        // Other RSA primes info optional, default to empty list
1132                        if (oth != null) {
1133                                this.oth = Collections.unmodifiableList(oth);
1134                        } else {
1135                                this.oth = Collections.emptyList();
1136                        }
1137
1138                } else if (p == null && q == null && dp == null && dq == null && qi == null && oth == null) {
1139
1140                        // No CRT params
1141                        this.p = null;
1142                        this.q = null;
1143                        this.dp = null;
1144                        this.dq = null;
1145                        this.qi = null;
1146
1147                        this.oth = Collections.emptyList();
1148
1149                } else {
1150
1151                        if (p == null) {
1152                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first prime factor must not be null");
1153                        } else if (q == null) {
1154                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second prime factor must not be null");
1155                        } else if (dp == null) {
1156                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first factor CRT exponent must not be null");
1157                        } else if (dq == null) {
1158                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second factor CRT exponent must not be null");
1159                        } else { // qi == null
1160                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first CRT coefficient must not be null");
1161                        }
1162                }
1163        }
1164
1165
1166        /**
1167         * Creates a new public RSA JSON Web Key (JWK) with the specified
1168         * parameters.
1169         * 
1170         * @param pub The public RSA key to represent. Must not be 
1171         *            {@code null}.
1172         * @param use The key use, {@code null} if not specified or if the key
1173         *            is intended for signing as well as encryption.
1174         * @param ops The key operations, {@code null} if not specified.
1175         * @param alg The intended JOSE algorithm for the key, {@code null} if
1176         *            not specified.
1177         * @param kid The key ID. {@code null} if not specified.
1178         * @param x5u The X.509 certificate URL, {@code null} if not specified.
1179         * @param x5t The X.509 certificate thumbprint, {@code null} if not
1180         *            specified.
1181         * @param x5c The X.509 certificate chain, {@code null} if not 
1182         *            specified.
1183         */
1184        public RSAKey(final RSAPublicKey pub,
1185                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1186                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1187
1188                this(Base64URL.encode(pub.getModulus()),
1189                        Base64URL.encode(pub.getPublicExponent()),
1190                        use, ops, alg, kid,
1191                        x5u, x5t, x5c);
1192        }
1193
1194
1195        /**
1196         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1197         * specified parameters. The private RSA key is specified by its first
1198         * representation (see RFC 3447, section 3.2).
1199         * 
1200         * @param pub  The public RSA key to represent. Must not be 
1201         *             {@code null}.
1202         * @param priv The private RSA key to represent. Must not be
1203         *             {@code null}.
1204         * @param use  The key use, {@code null} if not specified or if the key
1205         *             is intended for signing as well as encryption.
1206         * @param ops  The key operations, {@code null} if not specified.
1207         * @param alg  The intended JOSE algorithm for the key, {@code null} if
1208         *             not specified.
1209         * @param kid  The key ID. {@code null} if not specified.
1210         * @param x5u  The X.509 certificate URL, {@code null} if not
1211         *             specified.
1212         * @param x5t  The X.509 certificate thumbprint, {@code null} if not
1213         *             specified.
1214         * @param x5c  The X.509 certificate chain, {@code null} if not
1215         *             specified.
1216         */
1217        public RSAKey(final RSAPublicKey pub, final RSAPrivateKey priv,
1218                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1219                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1220                
1221                this(Base64URL.encode(pub.getModulus()), 
1222                     Base64URL.encode(pub.getPublicExponent()), 
1223                     Base64URL.encode(priv.getPrivateExponent()),
1224                     use, ops, alg, kid,
1225                     x5u, x5t, x5c);
1226        }
1227
1228
1229        /**
1230         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1231         * specified parameters. The private RSA key is specified by its second
1232         * representation (see RFC 3447, section 3.2).
1233         * 
1234         * @param pub  The public RSA key to represent. Must not be 
1235         *             {@code null}.
1236         * @param priv The private RSA key to represent. Must not be
1237         *             {@code null}.
1238         * @param use  The key use, {@code null} if not specified or if the key
1239         *             is intended for signing as well as encryption.
1240         * @param ops  The key operations, {@code null} if not specified.
1241         * @param alg  The intended JOSE algorithm for the key, {@code null} if
1242         *             not specified.
1243         * @param kid  The key ID. {@code null} if not specified.
1244         * @param x5u  The X.509 certificate URL, {@code null} if not
1245         *             specified.
1246         * @param x5t  The X.509 certificate thumbprint, {@code null} if not
1247         *             specified.
1248         * @param x5c  The X.509 certificate chain, {@code null} if not
1249         *             specified.
1250         */
1251        public RSAKey(final RSAPublicKey pub, final RSAPrivateCrtKey priv,
1252                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1253                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1254                
1255                this(Base64URL.encode(pub.getModulus()), 
1256                     Base64URL.encode(pub.getPublicExponent()), 
1257                     Base64URL.encode(priv.getPrivateExponent()),
1258                     Base64URL.encode(priv.getPrimeP()),
1259                     Base64URL.encode(priv.getPrimeQ()),
1260                     Base64URL.encode(priv.getPrimeExponentP()),
1261                     Base64URL.encode(priv.getPrimeExponentQ()),
1262                     Base64URL.encode(priv.getCrtCoefficient()),
1263                     null,
1264                     use, ops, alg, kid,
1265                     x5u, x5t, x5c);
1266        }
1267
1268
1269        /**
1270         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1271         * specified parameters. The private RSA key is specified by its second
1272         * representation, with optional other primes info (see RFC 3447, 
1273         * section 3.2).
1274         * 
1275         * @param pub  The public RSA key to represent. Must not be 
1276         *             {@code null}.
1277         * @param priv The private RSA key to represent. Must not be
1278         *             {@code null}.
1279         * @param use  The key use, {@code null} if not specified or if the key
1280         *             is intended for signing as well as encryption.
1281         * @param ops  The key operations, {@code null} if not specified.
1282         * @param alg  The intended JOSE algorithm for the key, {@code null} if
1283         *             not specified.
1284         * @param kid  The key ID. {@code null} if not specified.
1285         * @param x5u  The X.509 certificate URL, {@code null} if not
1286         *             specified.
1287         * @param x5t  The X.509 certificate thumbprint, {@code null} if not
1288         *             specified.
1289         * @param x5c  The X.509 certificate chain, {@code null} if not
1290         *             specified.
1291         */
1292        public RSAKey(final RSAPublicKey pub, final RSAMultiPrimePrivateCrtKey priv,
1293                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1294                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1295                
1296                this(Base64URL.encode(pub.getModulus()), 
1297                     Base64URL.encode(pub.getPublicExponent()), 
1298                     Base64URL.encode(priv.getPrivateExponent()),
1299                     Base64URL.encode(priv.getPrimeP()),
1300                     Base64URL.encode(priv.getPrimeQ()),
1301                     Base64URL.encode(priv.getPrimeExponentP()),
1302                     Base64URL.encode(priv.getPrimeExponentQ()),
1303                     Base64URL.encode(priv.getCrtCoefficient()),
1304                     OtherPrimesInfo.toList(priv.getOtherPrimeInfo()),
1305                     use, ops, alg, kid,
1306                     x5u, x5t, x5c);
1307        }
1308
1309
1310        /**
1311         * Gets the modulus value ({@code n}) of the RSA key.
1312         *
1313         * @return The RSA key modulus. It is represented as the Base64URL 
1314         *         encoding of the value's big endian representation.
1315         */
1316        public Base64URL getModulus() {
1317
1318                return n;
1319        }
1320
1321
1322        /**
1323         * Gets the public exponent ({@code e}) of the RSA key.
1324         *
1325         * @return The public RSA key exponent. It is represented as the 
1326         *         Base64URL encoding of the value's big endian representation.
1327         */
1328        public Base64URL getPublicExponent() {
1329
1330                return e;
1331        }
1332
1333
1334        /**
1335         * Gets the private exponent ({@code d}) of the RSA key.
1336         *
1337         * @return The private RSA key exponent. It is represented as the 
1338         *         Base64URL encoding of the value's big endian representation. 
1339         *         {@code null} if not specified (for a public key or a private
1340         *         key using the second representation only).
1341         */
1342        public Base64URL getPrivateExponent() {
1343
1344                return d;
1345        }
1346
1347
1348        /**
1349         * Gets the first prime factor ({@code p}) of the private RSA key. 
1350         *
1351         * @return The RSA first prime factor. It is represented as the 
1352         *         Base64URL encoding of the value's big endian representation. 
1353         *         {@code null} if not specified (for a public key or a private
1354         *         key using the first representation only).
1355         */
1356        public Base64URL getFirstPrimeFactor() {
1357
1358                return p;
1359        }
1360
1361
1362        /**
1363         * Gets the second prime factor ({@code q}) of the private RSA key.
1364         *
1365         * @return The RSA second prime factor. It is represented as the 
1366         *         Base64URL encoding of the value's big endian representation. 
1367         *         {@code null} if not specified (for a public key or a private
1368         *         key using the first representation only).
1369         */
1370        public Base64URL getSecondPrimeFactor() {
1371
1372                return q;
1373        }
1374
1375
1376        /**
1377         * Gets the first factor Chinese Remainder Theorem (CRT) exponent
1378         * ({@code dp}) of the private RSA key.
1379         *
1380         * @return The RSA first factor CRT exponent. It is represented as the 
1381         *         Base64URL encoding of the value's big endian representation. 
1382         *         {@code null} if not specified (for a public key or a private
1383         *         key using the first representation only).
1384         */
1385        public Base64URL getFirstFactorCRTExponent() {
1386
1387                return dp;
1388        }
1389
1390
1391        /**
1392         * Gets the second factor Chinese Remainder Theorem (CRT) exponent 
1393         * ({@code dq}) of the private RSA key.
1394         *
1395         * @return The RSA second factor CRT exponent. It is represented as the 
1396         *         Base64URL encoding of the value's big endian representation. 
1397         *         {@code null} if not specified (for a public key or a private
1398         *         key using the first representation only).
1399         */
1400        public Base64URL getSecondFactorCRTExponent() {
1401
1402                return dq;
1403        }
1404
1405
1406        /**
1407         * Gets the first Chinese Remainder Theorem (CRT) coefficient
1408         * ({@code qi})} of the private RSA key.
1409         *
1410         * @return The RSA first CRT coefficient. It is represented as the 
1411         *         Base64URL encoding of the value's big endian representation. 
1412         *         {@code null} if not specified (for a public key or a private
1413         *         key using the first representation only).
1414         */
1415        public Base64URL getFirstCRTCoefficient() {
1416
1417                return qi;
1418        }
1419
1420
1421        /**
1422         * Gets the other primes information ({@code oth}) for the private RSA
1423         * key, should they exist.
1424         *
1425         * @return The RSA other primes information, {@code null} or empty list
1426         *         if not specified.
1427         */
1428        public List<OtherPrimesInfo> getOtherPrimes() {
1429
1430                return oth;
1431        }
1432
1433        
1434        /**
1435         * Returns a standard {@code java.security.interfaces.RSAPublicKey} 
1436         * representation of this RSA JWK.
1437         * 
1438         * @return The public RSA key.
1439         * 
1440         * @throws JOSEException If RSA is not supported by the underlying Java
1441         *                       Cryptography (JCA) provider or if the JWK
1442         *                       parameters are invalid for a public RSA key.
1443         */
1444        public RSAPublicKey toRSAPublicKey() 
1445                throws JOSEException {
1446
1447                BigInteger modulus = n.decodeToBigInteger();
1448                BigInteger exponent = e.decodeToBigInteger();
1449                                
1450                RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
1451
1452                try {
1453                        KeyFactory factory = KeyFactory.getInstance("RSA");
1454
1455                        return (RSAPublicKey) factory.generatePublic(spec);
1456
1457                } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
1458
1459                        throw new JOSEException(e.getMessage(), e);
1460                }
1461        }
1462        
1463
1464        /**
1465         * Returns a standard {@code java.security.interfaces.RSAPrivateKey} 
1466         * representation of this RSA JWK.
1467         * 
1468         * @return The private RSA key, {@code null} if not specified by this
1469         *         JWK.
1470         * 
1471         * @throws JOSEException If RSA is not supported by the underlying Java
1472         *                       Cryptography (JCA) provider or if the JWK
1473         *                       parameters are invalid for a private RSA key.
1474         */
1475        public RSAPrivateKey toRSAPrivateKey() 
1476                throws JOSEException {
1477                
1478                if (d == null) {
1479                        // no private key
1480                        return null;
1481                }
1482                
1483                BigInteger modulus = n.decodeToBigInteger();
1484                BigInteger privateExponent = d.decodeToBigInteger();
1485                
1486                RSAPrivateKeySpec spec;
1487
1488                if (p == null) {
1489                        // Use 1st representation
1490                        spec = new RSAPrivateKeySpec(modulus, privateExponent);
1491
1492                } else {
1493                        // Use 2nd (CRT) representation
1494                        BigInteger publicExponent = e.decodeToBigInteger();
1495                        BigInteger primeP = p.decodeToBigInteger();
1496                        BigInteger primeQ = q.decodeToBigInteger();
1497                        BigInteger primeExponentP = dp.decodeToBigInteger();
1498                        BigInteger primeExponentQ = dq.decodeToBigInteger();
1499                        BigInteger crtCoefficient = qi.decodeToBigInteger();
1500
1501                        if (oth != null && ! oth.isEmpty()) {
1502                                // Construct other info spec
1503                                RSAOtherPrimeInfo[] otherInfo = new RSAOtherPrimeInfo[oth.size()];
1504
1505                                for (int i=0; i < oth.size(); i++) {
1506
1507                                        OtherPrimesInfo opi = oth.get(i);
1508
1509                                        BigInteger otherPrime = opi.getPrimeFactor().decodeToBigInteger();
1510                                        BigInteger otherPrimeExponent = opi.getFactorCRTExponent().decodeToBigInteger();
1511                                        BigInteger otherCrtCoefficient = opi.getFactorCRTCoefficient().decodeToBigInteger();
1512
1513                                        otherInfo[i] = new RSAOtherPrimeInfo(otherPrime,
1514                                                                             otherPrimeExponent,
1515                                                                             otherCrtCoefficient);
1516                                }
1517
1518                                spec = new RSAMultiPrimePrivateCrtKeySpec(modulus,
1519                                                                          publicExponent,
1520                                                                          privateExponent,
1521                                                                          primeP,
1522                                                                          primeQ,
1523                                                                          primeExponentP,
1524                                                                          primeExponentQ,
1525                                                                          crtCoefficient,
1526                                                                          otherInfo);
1527                        } else {
1528                                // Construct spec with no other info
1529                                spec = new RSAPrivateCrtKeySpec(modulus,
1530                                                                publicExponent,
1531                                                                privateExponent,
1532                                                                primeP,
1533                                                                primeQ,
1534                                                                primeExponentP,
1535                                                                primeExponentQ,
1536                                                                crtCoefficient);        
1537                        } 
1538                }
1539
1540                try {
1541                        KeyFactory factory = KeyFactory.getInstance("RSA");
1542
1543                        return (RSAPrivateKey) factory.generatePrivate(spec);
1544
1545                } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
1546
1547                        throw new JOSEException(e.getMessage(), e);
1548                }
1549        }
1550
1551
1552        @Override
1553        public PublicKey toPublicKey()
1554                throws JOSEException {
1555
1556                return toRSAPublicKey();
1557        }
1558
1559
1560        @Override
1561        public PrivateKey toPrivateKey()
1562                throws JOSEException {
1563
1564                return toRSAPrivateKey();
1565        }
1566
1567
1568        /**
1569         * Returns a standard {@code java.security.KeyPair} representation of 
1570         * this RSA JWK.
1571         * 
1572         * @return The RSA key pair. The private RSA key will be {@code null} 
1573         *         if not specified.
1574         * 
1575         * @throws JOSEException If RSA is not supported by the underlying Java
1576         *                       Cryptography (JCA) provider or if the JWK
1577         *                       parameters are invalid for a public and / or
1578         *                       private RSA key.
1579         */
1580        @Override
1581        public KeyPair toKeyPair() 
1582                throws JOSEException {
1583                
1584                return new KeyPair(toRSAPublicKey(), toRSAPrivateKey());
1585        }
1586
1587
1588        @Override
1589        public LinkedHashMap<String,?> getRequiredParams() {
1590
1591                // Put mandatory params in sorted order
1592                LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>();
1593                requiredParams.put("e", e.toString());
1594                requiredParams.put("kty", getKeyType().getValue());
1595                requiredParams.put("n", n.toString());
1596                return requiredParams;
1597        }
1598
1599
1600        @Override
1601        public boolean isPrivate() {
1602
1603                // Check if 1st or 2nd form params are specified
1604                return d != null || p != null;
1605        }
1606
1607
1608        @Override
1609        public int size() {
1610
1611                return ByteUtils.bitLength(n.decode());
1612        }
1613
1614
1615        /**
1616         * Returns a copy of this RSA JWK with any private values removed.
1617         *
1618         * @return The copied public RSA JWK.
1619         */
1620        @Override
1621        public RSAKey toPublicJWK() {
1622
1623                return new RSAKey(getModulus(), getPublicExponent(),
1624                                  getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(),
1625                                  getX509CertURL(), getX509CertThumbprint(), getX509CertChain());
1626        }
1627        
1628        
1629        @Override
1630        public JSONObject toJSONObject() {
1631
1632                JSONObject o = super.toJSONObject();
1633
1634                // Append public RSA key specific attributes
1635                o.put("n", n.toString());
1636                o.put("e", e.toString());
1637                if (d != null) {
1638                        o.put("d", d.toString());
1639                }
1640                if (p != null) {
1641                        o.put("p", p.toString());
1642                }
1643                if (q != null) {
1644                        o.put("q", q.toString());
1645                }
1646                if (dp != null) {
1647                        o.put("dp", dp.toString());
1648                }
1649                if (dq != null) {
1650                        o.put("dq", dq.toString());
1651                }
1652                if (qi != null) {
1653                        o.put("qi", qi.toString());
1654                }
1655                if (oth != null && !oth.isEmpty()) {
1656
1657                        JSONArray a = new JSONArray();
1658
1659                        for (OtherPrimesInfo other : oth) {
1660
1661                                JSONObject oo = new JSONObject();
1662                                oo.put("r", other.r.toString());
1663                                oo.put("d", other.d.toString());
1664                                oo.put("t", other.t.toString());
1665
1666                                a.add(oo);
1667                        }
1668
1669                        o.put("oth", a);
1670                }
1671
1672                return o;
1673        }
1674
1675
1676        /**
1677         * Parses a public / private RSA Curve JWK from the specified JSON
1678         * object string representation.
1679         *
1680         * @param s The JSON object string to parse. Must not be {@code null}.
1681         *
1682         * @return The public / private RSA JWK.
1683         *
1684         * @throws ParseException If the string couldn't be parsed to an RSA
1685         *                        JWK.
1686         */
1687        public static RSAKey parse(final String s)
1688                throws ParseException {
1689
1690                return parse(JSONObjectUtils.parse(s));
1691        }
1692
1693
1694        /**
1695         * Parses a public / private RSA JWK from the specified JSON object 
1696         * representation.
1697         *
1698         * @param jsonObject The JSON object to parse. Must not be 
1699         *                   {@code null}.
1700         *
1701         * @return The public / private RSA Key.
1702         *
1703         * @throws ParseException If the JSON object couldn't be parsed to an
1704         *                        RSA JWK.
1705         */
1706        public static RSAKey parse(final JSONObject jsonObject)
1707                throws ParseException {
1708
1709                // Parse the mandatory public key parameters first
1710                Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n"));
1711                Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e"));
1712
1713                // Check key type
1714                KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty"));
1715                if (kty != KeyType.RSA) {
1716                        throw new ParseException("The key type \"kty\" must be RSA", 0);
1717                }
1718                
1719                // Parse the optional private key parameters
1720
1721                // 1st private representation
1722                Base64URL d = null;
1723                if (jsonObject.containsKey("d")) {
1724                        d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d"));
1725                }
1726
1727                // 2nd private (CRT) representation
1728                Base64URL p = null;
1729                if (jsonObject.containsKey("p")) {
1730                        p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p"));
1731                }
1732                Base64URL q = null;
1733                if (jsonObject.containsKey("q")) {
1734                        q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q"));
1735                }
1736                Base64URL dp = null;
1737                if (jsonObject.containsKey("dp")) {
1738                        dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp"));
1739                }
1740                Base64URL dq= null;
1741                if (jsonObject.containsKey("dq")) {
1742                        dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq"));
1743                }
1744                Base64URL qi = null;
1745                if (jsonObject.containsKey("qi")) {
1746                        qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi"));
1747                }
1748                
1749                List<OtherPrimesInfo> oth = null;
1750                if (jsonObject.containsKey("oth")) {
1751
1752                        JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth");
1753                        oth = new ArrayList<>(arr.size());
1754                        
1755                        for (Object o : arr) {
1756
1757                                if (o instanceof JSONObject) {
1758                                        JSONObject otherJson = (JSONObject)o;
1759
1760                                        Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r"));
1761                                        Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq"));
1762                                        Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t"));
1763
1764                                        OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t);
1765                                        oth.add(prime);
1766                                }
1767                        }
1768                }
1769
1770                try {
1771                        return new RSAKey(n, e, d, p, q, dp, dq, qi, oth,
1772                                JWKMetadata.parseKeyUse(jsonObject),
1773                                JWKMetadata.parseKeyOperations(jsonObject),
1774                                JWKMetadata.parseAlgorithm(jsonObject),
1775                                JWKMetadata.parseKeyID(jsonObject),
1776                                JWKMetadata.parseX509CertURL(jsonObject),
1777                                JWKMetadata.parseX509CertThumbprint(jsonObject),
1778                                JWKMetadata.parseX509CertChain(jsonObject));
1779                
1780                } catch (IllegalArgumentException ex) {
1781
1782                        // Inconsistent 2nd spec, conflicting 'use' and 'key_ops'
1783                        throw new ParseException(ex.getMessage(), 0);
1784                }
1785        }
1786}