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