001package com.nimbusds.jose.jwk;
002
003
004import java.net.URL;
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 net.jcip.annotations.Immutable;
026
027import net.minidev.json.JSONArray;
028import net.minidev.json.JSONObject;
029
030import com.nimbusds.jose.Algorithm;
031import com.nimbusds.jose.util.Base64;
032import com.nimbusds.jose.util.Base64URL;
033import com.nimbusds.jose.util.JSONObjectUtils;
034import com.nimbusds.jose.util.X509CertChainUtils;
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 $version$ (2014-04-02)
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 URL 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 URL 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 URL 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 URL 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 URL 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 URL 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 URL 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 URL 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 URL 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 URL 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 NoSuchAlgorithmException If RSA is not supported by the
1390         *                                  underlying Java Cryptography (JCA)
1391         *                                  provider.
1392         * @throws InvalidKeySpecException  If the JWK key parameters are 
1393         *                                  invalid for a public RSA key.
1394         */
1395        public RSAPublicKey toRSAPublicKey() 
1396                throws NoSuchAlgorithmException, InvalidKeySpecException {
1397
1398                BigInteger modulus = n.decodeToBigInteger();
1399                BigInteger exponent = e.decodeToBigInteger();
1400                                
1401                RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
1402                KeyFactory factory = KeyFactory.getInstance("RSA");
1403                
1404                return (RSAPublicKey)factory.generatePublic(spec);
1405        }
1406        
1407
1408        /**
1409         * Returns a standard {@code java.security.interfaces.RSAPrivateKey} 
1410         * representation of this RSA JWK.
1411         * 
1412         * @return The private RSA key, {@code null} if not specified by this
1413         *         JWK.
1414         * 
1415         * @throws NoSuchAlgorithmException If RSA is not supported by the
1416         *                                  underlying Java Cryptography (JCA)
1417         *                                  provider.
1418         * @throws InvalidKeySpecException  If the JWK key parameters are 
1419         *                                  invalid for a private RSA key.
1420         */
1421        public RSAPrivateKey toRSAPrivateKey() 
1422                throws NoSuchAlgorithmException, InvalidKeySpecException {
1423                
1424                if (d == null) {
1425                        // no private key
1426                        return null;
1427                }
1428                
1429                BigInteger modulus = n.decodeToBigInteger();
1430                BigInteger privateExponent = d.decodeToBigInteger();
1431                
1432                RSAPrivateKeySpec spec;
1433
1434                if (p == null) {
1435                        // Use 1st representation
1436                        spec = new RSAPrivateKeySpec(modulus, privateExponent);
1437
1438                } else {
1439                        // Use 2nd (CRT) representation
1440                        BigInteger publicExponent = e.decodeToBigInteger();
1441                        BigInteger primeP = p.decodeToBigInteger();
1442                        BigInteger primeQ = q.decodeToBigInteger();
1443                        BigInteger primeExponentP = dp.decodeToBigInteger();
1444                        BigInteger primeExponentQ = dq.decodeToBigInteger();
1445                        BigInteger crtCoefficient = qi.decodeToBigInteger();
1446
1447                        if (oth != null && ! oth.isEmpty()) {
1448                                // Construct other info spec
1449                                RSAOtherPrimeInfo[] otherInfo = new RSAOtherPrimeInfo[oth.size()];
1450
1451                                for (int i=0; i < oth.size(); i++) {
1452
1453                                        OtherPrimesInfo opi = oth.get(i);
1454
1455                                        BigInteger otherPrime = opi.getPrimeFactor().decodeToBigInteger();
1456                                        BigInteger otherPrimeExponent = opi.getFactorCRTExponent().decodeToBigInteger();
1457                                        BigInteger otherCrtCoefficient = opi.getFactorCRTCoefficient().decodeToBigInteger();
1458
1459                                        otherInfo[i] = new RSAOtherPrimeInfo(otherPrime,
1460                                                                             otherPrimeExponent,
1461                                                                             otherCrtCoefficient);
1462                                }
1463
1464                                spec = new RSAMultiPrimePrivateCrtKeySpec(modulus,
1465                                                                          publicExponent,
1466                                                                          privateExponent,
1467                                                                          primeP,
1468                                                                          primeQ,
1469                                                                          primeExponentP,
1470                                                                          primeExponentQ,
1471                                                                          crtCoefficient,
1472                                                                          otherInfo);
1473                        } else {
1474                                // Construct spec with no other info
1475                                spec = new RSAPrivateCrtKeySpec(modulus,
1476                                                                publicExponent,
1477                                                                privateExponent,
1478                                                                primeP,
1479                                                                primeQ,
1480                                                                primeExponentP,
1481                                                                primeExponentQ,
1482                                                                crtCoefficient);        
1483                        } 
1484                }
1485                
1486                KeyFactory factory = KeyFactory.getInstance("RSA");
1487                
1488                return (RSAPrivateKey)factory.generatePrivate(spec);
1489        }
1490
1491
1492        /**
1493         * Returns a standard {@code java.security.KeyPair} representation of 
1494         * this RSA JWK.
1495         * 
1496         * @return The RSA key pair. The private RSA key will be {@code null} 
1497         *         if not specified.
1498         * 
1499         * @throws NoSuchAlgorithmException If RSA is not supported by the
1500         *                                  underlying Java Cryptography (JCA)
1501         *                                  provider.
1502         * @throws InvalidKeySpecException  If the JWK key parameters are 
1503         *                                  invalid for a public and / or 
1504         *                                  private RSA key.
1505         */
1506        public KeyPair toKeyPair() 
1507                throws NoSuchAlgorithmException, InvalidKeySpecException {
1508                
1509                return new KeyPair(toRSAPublicKey(), toRSAPrivateKey());
1510        }
1511
1512
1513        @Override
1514        public boolean isPrivate() {
1515
1516                // Check if 1st or 2nd form params are specified
1517                return d != null || p != null;
1518        }
1519
1520
1521        /**
1522         * Returns a copy of this RSA JWK with any private values removed.
1523         *
1524         * @return The copied public RSA JWK.
1525         */
1526        @Override
1527        public RSAKey toPublicJWK() {
1528
1529                return new RSAKey(getModulus(), getPublicExponent(),
1530                                  getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(),
1531                                  getX509CertURL(), getX509CertThumbprint(), getX509CertChain());
1532        }
1533        
1534        
1535        @Override
1536        public JSONObject toJSONObject() {
1537
1538                JSONObject o = super.toJSONObject();
1539
1540                // Append public RSA key specific attributes
1541                o.put("n", n.toString());
1542                o.put("e", e.toString());
1543                if (d != null) {
1544                        o.put("d", d.toString());
1545                }
1546                if (p != null) {
1547                        o.put("p", p.toString());
1548                }
1549                if (q != null) {
1550                        o.put("q", q.toString());
1551                }
1552                if (dp != null) {
1553                        o.put("dp", dp.toString());
1554                }
1555                if (dq != null) {
1556                        o.put("dq", dq.toString());
1557                }
1558                if (qi != null) {
1559                        o.put("qi", qi.toString());
1560                }
1561                if (oth != null && !oth.isEmpty()) {
1562
1563                        JSONArray a = new JSONArray();
1564
1565                        for (OtherPrimesInfo other : oth) {
1566
1567                                JSONObject oo = new JSONObject();
1568                                oo.put("r", other.r.toString());
1569                                oo.put("d", other.d.toString());
1570                                oo.put("t", other.t.toString());
1571
1572                                a.add(oo);
1573                        }
1574
1575                        o.put("oth", a);
1576                }
1577
1578                return o;
1579        }
1580
1581
1582        /**
1583         * Parses a public / private RSA Curve JWK from the specified JSON
1584         * object string representation.
1585         *
1586         * @param s The JSON object string to parse. Must not be {@code null}.
1587         *
1588         * @return The public / private RSA JWK.
1589         *
1590         * @throws ParseException If the string couldn't be parsed to an RSA
1591         *                        JWK.
1592         */
1593        public static RSAKey parse(final String s)
1594                throws ParseException {
1595
1596                return parse(JSONObjectUtils.parseJSONObject(s));
1597        }
1598
1599
1600        /**
1601         * Parses a public / private RSA JWK from the specified JSON object 
1602         * representation.
1603         *
1604         * @param jsonObject The JSON object to parse. Must not be 
1605         *                   @code null}.
1606         *
1607         * @return The public / private RSA Key.
1608         *
1609         * @throws ParseException If the JSON object couldn't be parsed to an
1610         *                        RSA JWK.
1611         */
1612        public static RSAKey parse(final JSONObject jsonObject)
1613                throws ParseException {
1614
1615                // Parse the mandatory public key parameters first
1616                Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n"));
1617                Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e"));
1618
1619                // Check key type
1620                KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty"));
1621                if (kty != KeyType.RSA) {
1622                        throw new ParseException("The key type \"kty\" must be RSA", 0);
1623                }
1624                
1625                // Parse the optional private key parameters
1626
1627                // 1st private representation
1628                Base64URL d = null;
1629                if (jsonObject.containsKey("d")) {
1630                        d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d"));
1631                }
1632
1633                // 2nd private (CRT) representation
1634                Base64URL p = null;
1635                if (jsonObject.containsKey("p")) {
1636                        p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p"));
1637                }
1638                Base64URL q = null;
1639                if (jsonObject.containsKey("q")) {
1640                        q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q"));
1641                }
1642                Base64URL dp = null;
1643                if (jsonObject.containsKey("dp")) {
1644                        dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp"));
1645                }
1646                Base64URL dq= null;
1647                if (jsonObject.containsKey("dq")) {
1648                        dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq"));
1649                }
1650                Base64URL qi = null;
1651                if (jsonObject.containsKey("qi")) {
1652                        qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi"));
1653                }
1654                
1655                List<OtherPrimesInfo> oth = null;
1656                if (jsonObject.containsKey("oth")) {
1657
1658                        JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth");
1659                        oth = new ArrayList<>(arr.size());
1660                        
1661                        for (Object o : arr) {
1662
1663                                if (o instanceof JSONObject) {
1664                                        JSONObject otherJson = (JSONObject)o;
1665
1666                                        Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r"));
1667                                        Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq"));
1668                                        Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t"));
1669
1670                                        OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t);
1671                                        oth.add(prime);
1672                                }
1673                        }
1674                }
1675                
1676                // Get optional key use
1677                KeyUse use = null;
1678
1679                if (jsonObject.containsKey("use")) {
1680                        use = KeyUse.parse(JSONObjectUtils.getString(jsonObject, "use"));
1681                }
1682
1683                // Get optional key operations
1684                Set<KeyOperation> ops = null;
1685
1686                if (jsonObject.containsKey("key_ops")) {
1687                        ops = KeyOperation.parse(JSONObjectUtils.getStringList(jsonObject, "key_ops"));
1688                }
1689
1690                // Get optional intended algorithm
1691                Algorithm alg = null;
1692
1693                if (jsonObject.containsKey("alg")) {
1694                        alg = new Algorithm(JSONObjectUtils.getString(jsonObject, "alg"));
1695                }
1696
1697                // Get optional key ID
1698                String kid = null;
1699
1700                if (jsonObject.containsKey("kid")) {
1701                        kid = JSONObjectUtils.getString(jsonObject, "kid");
1702                }
1703
1704                // Get optional X.509 cert URL
1705                URL x5u = null;
1706
1707                if (jsonObject.containsKey("x5u")) {
1708                        x5u = JSONObjectUtils.getURL(jsonObject, "x5u");        
1709                }
1710
1711                // Get optional X.509 cert thumbprint
1712                Base64URL x5t = null;
1713
1714                if (jsonObject.containsKey("x5t")) {
1715                        x5t = new Base64URL(JSONObjectUtils.getString(jsonObject, "x5t"));
1716                }
1717
1718                // Get optional X.509 cert chain
1719                List<Base64> x5c = null;
1720
1721                if (jsonObject.containsKey("x5c")) {
1722                        x5c = X509CertChainUtils.parseX509CertChain(JSONObjectUtils.getJSONArray(jsonObject, "x5c"));   
1723                }
1724
1725                try {
1726                        return new RSAKey(n, e, d, p, q, dp, dq, qi, oth, use, ops, alg, kid, x5u, x5t, x5c);
1727                
1728                } catch (IllegalArgumentException ex) {
1729
1730                        // Inconsistent 2nd spec, conflicting 'use' and 'key_ops'
1731                        throw new ParseException(ex.getMessage(), 0);
1732                }
1733        }
1734}