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