001 package com.nimbusds.jose;
002
003
004 import java.text.ParseException;
005
006 import net.minidev.json.JSONObject;
007
008 import net.jcip.annotations.Immutable;
009
010 import com.nimbusds.jose.util.Base64URL;
011 import com.nimbusds.jose.util.JSONObjectUtils;
012
013
014 /**
015 * Public {@link KeyType#RSA RSA} JSON Web Key (JWK). This class is immutable.
016 *
017 * <p>Example JSON:
018 *
019 * <pre>
020 * {
021 * "kty" : "RSA",
022 * "n" : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
023 * 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
024 * tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
025 * QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
026 * SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
027 * w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
028 * "e" : "AQAB",
029 * "alg" : "RS256"
030 * "kid" : "2011-04-29"}
031 * }
032 * </pre>
033 *
034 * <p>See http://en.wikipedia.org/wiki/RSA_%28algorithm%29
035 *
036 * @author Vladimir Dzhuvinov
037 * @version $version$ (2013-01-08)
038 */
039 @Immutable
040 public final class RSAKey extends JWK {
041
042
043 /**
044 * The modulus value for the RSA public key.
045 */
046 private final Base64URL n;
047
048
049 /**
050 * The exponent value for the RSA public key.
051 */
052 private final Base64URL e;
053
054
055 /**
056 * Creates a new public RSA JSON Web Key (JWK) with the specified
057 * parameters.
058 *
059 * @param n The the modulus value for the RSA public key. It is
060 * represented as the Base64URL encoding of value's big
061 * endian representation. Must not be {@code null}.
062 * @param e The exponent value for the RSA public key. It is
063 * represented as the Base64URL encoding of value's big
064 * endian representation. Must not be {@code null}.
065 * @param use The key use. {@code null} if not specified.
066 * @param alg The intended JOSE algorithm for the key, {@code null} if
067 * not specified.
068 * @param kid The key ID. {@code null} if not specified.
069 */
070 public RSAKey(final Base64URL n, final Base64URL e,
071 final Use use, final Algorithm alg, final String kid) {
072
073 super(KeyType.RSA, use, alg, kid);
074
075 if (n == null)
076 throw new IllegalArgumentException("The modulus value must not be null");
077
078 this.n = n;
079
080 if (e == null)
081 throw new IllegalArgumentException("The exponent value must not be null");
082
083 this.e = e;
084 }
085
086
087 /**
088 * Returns the modulus value for this RSA public key. It is represented
089 * as the Base64URL encoding of the value's big ending representation.
090 *
091 * @return The RSA public key modulus.
092 */
093 public Base64URL getModulus() {
094
095 return n;
096 }
097
098
099 /**
100 * Returns the exponent value for this RSA public key. It is represented
101 * as the Base64URL encoding of the value's big ending representation.
102 *
103 * @return The RSA public key exponent.
104 */
105 public Base64URL getExponent() {
106
107 return e;
108 }
109
110
111 @Override
112 public JSONObject toJSONObject() {
113
114 JSONObject o = super.toJSONObject();
115
116 // Append RSA public key specific attributes
117 o.put("n", n.toString());
118 o.put("e", e.toString());
119
120 return o;
121 }
122
123
124 /**
125 * Parses a public RSA JWK from the specified JSON object
126 * representation.
127 *
128 * @param jsonObject The JSON object to parse. Must not be
129 * @code null}.
130 *
131 * @return The RSA Key.
132 *
133 * @throws ParseException If the JSON object couldn't be parsed to valid
134 * RSA JWK.
135 */
136 public static RSAKey parse(final JSONObject jsonObject)
137 throws ParseException {
138
139 // Parse the mandatory parameters first
140 KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty"));
141 Base64URL mod = new Base64URL(JSONObjectUtils.getString(jsonObject, "n"));
142 Base64URL exp = new Base64URL(JSONObjectUtils.getString(jsonObject, "e"));
143
144 // Get optional key use
145 Use use = JWK.parseKeyUse(jsonObject);
146
147 // Get optional intended algorithm
148 Algorithm alg = JWK.parseAlgorithm(jsonObject);
149
150 // Get optional key ID
151 String id = JWK.parseKeyID(jsonObject);
152
153 // Check key type
154 if (kty != KeyType.RSA)
155 throw new ParseException("The key type \"kty\" must be RSA", 0);
156
157 return new RSAKey(mod, exp, use, alg, id);
158 }
159 }