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 }