001 package com.nimbusds.jose.jwk; 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.Algorithm; 010 import com.nimbusds.jose.util.Base64URL; 011 import com.nimbusds.jose.util.JSONObjectUtils; 012 013 014 /** 015 * {@link KeyType#OCT Octet sequence} JSON Web Key (JWK), used to represent 016 * symmetric keys. This class is immutable. 017 * 018 * <p>Example JSON object representation of an octet sequence JWK: 019 * 020 * <pre> 021 * { 022 * "kty" : "oct", 023 * "alg" : "A128KW", 024 * "k" : "GawgguFyGrWKav7AX4VKUg" 025 * } 026 * </pre> 027 * 028 * @author Justin Richer 029 * @author Vladimir Dzhuvinov 030 * @version $version$ (2013-03-26) 031 */ 032 @Immutable 033 public class OctetSequenceKey extends JWK { 034 035 036 /** 037 * The symmetric key value. 038 */ 039 private final Base64URL k; 040 041 042 /** 043 * Creates a new octet sequence JSON Web Key (JWK) with the specified 044 * parameters. 045 * 046 * @param k The key value. It is represented as the Base64URL 047 * encoding of value's big endian representation. Must not 048 * be {@code null}. 049 * @param use The key use. {@code null} if not specified. 050 * @param alg The intended JOSE algorithm for the key, {@code null} if 051 * not specified. 052 * @param kid The key ID. {@code null} if not specified. 053 */ 054 public OctetSequenceKey(final Base64URL k, final Use use, final Algorithm alg, final String kid) { 055 056 super(KeyType.OCT, use, alg, kid); 057 058 if (k == null) { 059 060 throw new IllegalArgumentException("The key value must not be null"); 061 } 062 063 this.k = k; 064 } 065 066 067 /** 068 * Creates a new octet sequence JSON Web Key (JWK) with the specified 069 * parameters. 070 * 071 * @param k The key value. It is represented as the value's big 072 * endian representation. Must not be {@code null}. 073 * @param use The key use. {@code null} if not specified. 074 * @param alg The intended JOSE algorithm for the key, {@code null} if 075 * not specified. 076 * @param kid The key ID. {@code null} if not specified. 077 */ 078 public OctetSequenceKey(final byte[] k, final Use use, final Algorithm alg, final String kid) { 079 080 super(KeyType.OCT, use, alg, kid); 081 082 if (k == null) { 083 084 throw new IllegalArgumentException("The key value must not be null"); 085 } 086 087 this.k = Base64URL.encode(k); 088 } 089 090 091 /** 092 * Returns the value of this octet sequence key. It is represented as 093 * the Base64URL encoding of the coordinate's big endian 094 * representation. 095 * 096 * @return The key value. 097 */ 098 public Base64URL getKeyValue() { 099 100 return k; 101 } 102 103 104 /** 105 * Returns a copy of this octet sequence key value as a byte array. 106 * 107 * @return The key value as a byte array. 108 */ 109 public byte[] toByteArray() { 110 111 return getKeyValue().decode(); 112 } 113 114 115 /** 116 * Octet sequence (symmetric) keys are never considered public, this 117 * method always returns {@code true}. 118 * 119 * @return {@code true} 120 */ 121 @Override 122 public boolean isPrivate() { 123 124 return true; 125 } 126 127 128 /** 129 * Octet sequence (symmetric) keys are never considered public, this 130 * method always returns {@code null}. 131 * 132 * @return {@code null} 133 */ 134 @Override 135 public OctetSequenceKey toPublicJWK() { 136 137 return null; 138 } 139 140 141 @Override 142 public JSONObject toJSONObject() { 143 144 JSONObject o = super.toJSONObject(); 145 146 // Append key value 147 o.put("k", k.toString()); 148 149 return o; 150 } 151 152 153 /** 154 * Parses an octet sequence JWK from the specified JSON object string 155 * representation. 156 * 157 * @param s The JSON object string to parse. Must not be {@code null}. 158 * 159 * @return The octet sequence JWK. 160 * 161 * @throws ParseException If the string couldn't be parsed to an octet 162 * sequence JWK. 163 */ 164 public static OctetSequenceKey parse(final String s) 165 throws ParseException { 166 167 return parse(JSONObjectUtils.parseJSONObject(s)); 168 } 169 170 171 /** 172 * Parses an octet sequence JWK from the specified JSON object 173 * representation. 174 * 175 * @param jsonObject The JSON object to parse. Must not be 176 * @code null}. 177 * 178 * @return The octet sequence JWK. 179 * 180 * @throws ParseException If the JSON object couldn't be parsed to an 181 * octet sequence JWK. 182 */ 183 public static OctetSequenceKey parse(final JSONObject jsonObject) 184 throws ParseException { 185 186 // Parse the mandatory parameters first 187 Base64URL k = new Base64URL(JSONObjectUtils.getString(jsonObject, "k")); 188 189 // Check key type 190 KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty")); 191 192 if (kty != KeyType.OCT) { 193 194 throw new ParseException("The key type \"kty\" must be oct", 0); 195 } 196 197 // Get optional key use 198 Use use = JWK.parseKeyUse(jsonObject); 199 200 // Get optional intended algorithm 201 Algorithm alg = JWK.parseAlgorithm(jsonObject); 202 203 // Get optional key ID 204 String kid = JWK.parseKeyID(jsonObject); 205 206 return new OctetSequenceKey(k, use, alg, kid); 207 } 208 }