commit
863693cf59
|
@ -19,8 +19,6 @@ public class Rsa extends AbstractJwk{
|
|||
private String mod;
|
||||
private String exp;
|
||||
|
||||
JsonObject object = new JsonObject();
|
||||
|
||||
public String getMod() {
|
||||
return mod;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package org.mitre.jwt.encryption;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
public enum JweAlgorithms {
|
||||
|
||||
//Key Derivation Function Values
|
||||
CS256("256"),
|
||||
CS384("384"),
|
||||
CS512("512"),
|
||||
//Encryption Method Values
|
||||
A128GCM("GCM"),
|
||||
A256GCM("GCM"),
|
||||
A128CBC("CBC"),
|
||||
A256CBC("CBC");
|
||||
|
||||
|
||||
|
||||
private final String value;
|
||||
|
||||
JweAlgorithms(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static String getByName(String name) {
|
||||
for (JweAlgorithms correspondingType : JweAlgorithms.values()) {
|
||||
if (correspondingType.toString().equals(name)) {
|
||||
return correspondingType.value;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"JweAlgorithm name " + name + " does not have a corresponding JweAlgorithm: expected one of [" + StringUtils.join(JweAlgorithms.values(), ", ") + "]");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,6 @@ package org.mitre.jwt.encryption;
|
|||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
|
@ -13,11 +12,11 @@ import org.mitre.jwe.model.Jwe;
|
|||
|
||||
public interface JweDecrypter {
|
||||
|
||||
public Jwe decrypt(String encryptedJwe, Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||
public Jwe decrypt(String encryptedJwe) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||
|
||||
public byte[] decryptCipherText(Jwe jwe, byte[] cek) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||
|
||||
public byte[] decryptEncryptionKey(Jwe jwe, Key privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||
public byte[] decryptEncryptionKey(Jwe jwe) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.mitre.jwt.encryption;
|
|||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
|
@ -19,11 +18,11 @@ import com.google.gson.JsonSyntaxException;
|
|||
|
||||
public interface JweEncrypter {
|
||||
|
||||
public byte[] encryptKey(Jwe jwe, byte[] cmk, Key publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException;
|
||||
public byte[] encryptKey(Jwe jwe, byte[] cmk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException;
|
||||
|
||||
public byte[] encryptClaims(Jwe jwe, byte[] cik) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException;
|
||||
|
||||
public Jwe encryptAndSign(Jwe jwe, Key publicKey) throws NoSuchAlgorithmException, JsonIOException, JsonSyntaxException, IOException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException;
|
||||
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException, JsonIOException, JsonSyntaxException, IOException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException;
|
||||
|
||||
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException;
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@ package org.mitre.jwt.encryption.impl;
|
|||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
|
@ -15,13 +16,16 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.mitre.jwe.model.Jwe;
|
||||
import org.mitre.jwt.encryption.AbstractJweDecrypter;
|
||||
import org.mitre.jwt.signer.impl.HmacSigner;
|
||||
import org.mitre.jwt.encryption.JweAlgorithms;
|
||||
|
||||
|
||||
public class RsaDecrypter extends AbstractJweDecrypter {
|
||||
|
||||
private PublicKey publicKey;
|
||||
private PrivateKey privateKey;
|
||||
|
||||
@Override
|
||||
public Jwe decrypt(String encryptedJwe, Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
||||
public Jwe decrypt(String encryptedJwe) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
||||
|
||||
Jwe jwe = Jwe.parse(encryptedJwe);
|
||||
|
||||
|
@ -29,39 +33,20 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
|||
if(alg.equals("RSA1_5") || alg.equals("RSA-OAEP") || alg.equals("ECDH-ES") || alg.equals("A128KW") || alg.equals("A256KW")) {
|
||||
|
||||
//decrypt to get cmk to be used for cek and cik
|
||||
jwe.setEncryptedKey(decryptEncryptionKey(jwe, privateKey));
|
||||
jwe.setEncryptedKey(decryptEncryptionKey(jwe));
|
||||
|
||||
//generation of cek and cik
|
||||
byte[] contentEncryptionKey = null;
|
||||
byte[] contentIntegrityKey = null;
|
||||
//check what the key length is
|
||||
String encMethod = jwe.getHeader().getKeyDerivationFunction();
|
||||
char[] array = encMethod.toCharArray();
|
||||
String keyBitLengthString = new String("" + array[2] + array[3] + array[4]);
|
||||
int keyBitLength = Integer.parseInt(keyBitLengthString);
|
||||
String kdf = jwe.getHeader().getKeyDerivationFunction();
|
||||
String keyLength = JweAlgorithms.getByName(kdf);
|
||||
int keyBitLength = Integer.parseInt(keyLength);
|
||||
//generate cek and cik
|
||||
contentEncryptionKey = generateContentKey(jwe.getEncryptedKey(), keyBitLength, "Encryption".getBytes());
|
||||
contentIntegrityKey = generateContentKey(jwe.getEncryptedKey(), keyBitLength, "Integrity".getBytes());
|
||||
|
||||
//decrypt ciphertext to get claims
|
||||
jwe.setCiphertext(decryptCipherText(jwe, contentEncryptionKey));
|
||||
|
||||
//generate signature for decrypted signature base in order to verify that decryption worked
|
||||
/*String signature = null;
|
||||
try {
|
||||
HmacSigner hmacSigner = new HmacSigner(contentIntegrityKey);
|
||||
signature = hmacSigner.generateSignature(jwe.getSignatureBase());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//verifys that the signature base was decrypted correctly
|
||||
if(signature != jwe.getSignature()){
|
||||
throw new IllegalArgumentException("Didn't decrypt correctly. Decoded Sig and generated Sig do not match. " +
|
||||
"Generated Signature is: " + signature + " while decoded sig is: " + jwe.getSignature());
|
||||
}*/
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException(jwe.getHeader().getEncryptionMethod() + " is not a valid decrypting algorithm");
|
||||
}
|
||||
|
@ -78,10 +63,9 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
|||
//TODO: should also check for A128GCM and A256GCM, but Cipher.getInstance() does not support the GCM mode. For now, don't use them
|
||||
if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC")) {
|
||||
|
||||
String delims = "[8,6]+";
|
||||
String[] mode = encMethod.split(delims);
|
||||
String mode = JweAlgorithms.getByName(encMethod);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("AES/" + mode[1] + "/PKCS5Padding");
|
||||
Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv));
|
||||
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
|
||||
|
||||
|
@ -95,11 +79,11 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public byte[] decryptEncryptionKey(Jwe jwe, Key privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||
public byte[] decryptEncryptionKey(Jwe jwe) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||
|
||||
if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
|
||||
byte[] contentMasterKey = cipher.doFinal(jwe.getEncryptedKey());
|
||||
|
||||
return contentMasterKey;
|
||||
|
@ -109,4 +93,20 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
|||
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public void setPublicKey(PublicKey publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public void setPrivateKey(PrivateKey privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@ package org.mitre.jwt.encryption.impl;
|
|||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -17,11 +18,15 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.mitre.jwe.model.Jwe;
|
||||
import org.mitre.jwt.encryption.AbstractJweEncrypter;
|
||||
import org.mitre.jwt.encryption.JweAlgorithms;
|
||||
import org.mitre.jwt.signer.impl.HmacSigner;
|
||||
|
||||
public class RsaEncrypter extends AbstractJweEncrypter {
|
||||
|
||||
private PublicKey publicKey;
|
||||
private PrivateKey privateKey;
|
||||
|
||||
public Jwe encryptAndSign(Jwe jwe, Key publicKey) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
|
||||
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
|
||||
|
||||
String alg = jwe.getHeader().getAlgorithm();
|
||||
String integrityAlg = jwe.getHeader().getIntegrity();
|
||||
|
@ -31,10 +36,9 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
|||
//generate random content master key
|
||||
|
||||
//check what the key length is
|
||||
String encMethod = jwe.getHeader().getKeyDerivationFunction();
|
||||
char[] array = encMethod.toCharArray();
|
||||
String keyBitLengthString = new String("" + array[2] + array[3] + array[4]);
|
||||
int keyBitLength = Integer.parseInt(keyBitLengthString);
|
||||
String kdf = jwe.getHeader().getKeyDerivationFunction();
|
||||
String keyLength = JweAlgorithms.getByName(kdf);
|
||||
int keyBitLength = Integer.parseInt(keyLength);
|
||||
|
||||
byte[] contentMasterKey = new byte[keyBitLength];
|
||||
new Random().nextBytes(contentMasterKey);
|
||||
|
@ -48,7 +52,7 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
|||
|
||||
//encrypt claims and cmk to get ciphertext and encrypted key
|
||||
jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey));
|
||||
jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey, publicKey));
|
||||
jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey));
|
||||
|
||||
//Signer must be hmac
|
||||
if(integrityAlg.equals("HS256") || integrityAlg.equals("HS384") || integrityAlg.equals("HS512")){
|
||||
|
@ -67,12 +71,12 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
|||
return jwe;
|
||||
}
|
||||
|
||||
public byte[] encryptKey(Jwe jwe, byte[] contentMasterKey, Key publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||
public byte[] encryptKey(Jwe jwe, byte[] contentMasterKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||
|
||||
if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
|
||||
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, getPublicKey());
|
||||
byte[] encryptedKey = cipher.doFinal(contentMasterKey);
|
||||
return encryptedKey;
|
||||
|
||||
|
@ -96,11 +100,10 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
|||
String encMethod = jwe.getHeader().getEncryptionMethod();
|
||||
//TODO: should also check for A128GCM and A256GCM, but Cipher.getInstance() does not support the GCM mode. For now, don't use them
|
||||
if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC")) {
|
||||
// FIXME: this is fragile
|
||||
String delims = "[8,6]+";
|
||||
String[] mode = encMethod.split(delims);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("AES/" + mode[1] + "/PKCS5Padding");
|
||||
String mode = JweAlgorithms.getByName(encMethod);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv));
|
||||
byte[] cipherText = cipher.doFinal(jwe.getCiphertext());
|
||||
return cipherText;
|
||||
|
@ -110,4 +113,20 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public void setPublicKey(PublicKey publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public void setPrivateKey(PrivateKey privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ import com.google.gson.JsonPrimitive;
|
|||
*
|
||||
*/
|
||||
public class ClaimSet {
|
||||
|
||||
private String jsonString;
|
||||
|
||||
// the LinkedHashMap preserves insertion order
|
||||
private Map<String, Object> claims = new LinkedHashMap<String, Object>();
|
||||
|
@ -94,6 +96,7 @@ public class ClaimSet {
|
|||
* Set an extension claim
|
||||
*/
|
||||
public void setClaim(String key, Object value) {
|
||||
jsonString = null;
|
||||
claims.put(key, value);
|
||||
}
|
||||
|
||||
|
@ -101,6 +104,7 @@ public class ClaimSet {
|
|||
* Set a primitive claim
|
||||
*/
|
||||
public void setClaim(String key, JsonPrimitive prim) {
|
||||
jsonString = null;
|
||||
if (prim == null) {
|
||||
// in case we get here with a primitive null
|
||||
claims.put(key, prim);
|
||||
|
@ -111,6 +115,7 @@ public class ClaimSet {
|
|||
} else if (prim.isString()) {
|
||||
claims.put(key, prim.getAsString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,4 +208,11 @@ public class ClaimSet {
|
|||
loadFromJsonObject(json);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if(jsonString == null) {
|
||||
jsonString = this.getAsJsonObject().toString();
|
||||
}
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import org.apache.commons.codec.binary.Base64;
|
|||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class Jwt {
|
||||
|
||||
|
@ -124,11 +123,9 @@ public class Jwt {
|
|||
* The signature base of a JWT is the header in Base64, a period ".", and the claims in Base64.
|
||||
*/
|
||||
public String getSignatureBase() {
|
||||
JsonObject h = header.getAsJsonObject();
|
||||
JsonObject c = claims.getAsJsonObject();
|
||||
|
||||
String h64 = new String(Base64.encodeBase64URLSafe(h.toString().getBytes()));
|
||||
String c64 = new String(Base64.encodeBase64URLSafe(c.toString().getBytes()));
|
||||
|
||||
String h64 = new String(Base64.encodeBase64URLSafe(header.toString().getBytes()));
|
||||
String c64 = new String(Base64.encodeBase64URLSafe(claims.toString().getBytes()));
|
||||
|
||||
return h64 + "." + c64;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
******************************************************************************/
|
||||
package org.mitre.jwt.model;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
@ -59,7 +60,12 @@ public class JwtHeader extends ClaimSet {
|
|||
if (element.getValue().isJsonNull()) {
|
||||
pass.add(element.getKey(), element.getValue());
|
||||
} else if (element.getKey().equals(TYPE)) {
|
||||
this.setType(element.getValue().getAsString());
|
||||
try {
|
||||
this.setType(element.getValue().getAsString());
|
||||
} catch (ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (element.getKey().equals(ALGORITHM)) {
|
||||
this.setAlgorithm(element.getValue().getAsString());
|
||||
} else if (element.getKey().equals(ENCRYPTION_METHOD)) {
|
||||
|
@ -85,9 +91,13 @@ public class JwtHeader extends ClaimSet {
|
|||
|
||||
/**
|
||||
* @param type the type to set
|
||||
* @throws ParseException
|
||||
*/
|
||||
public void setType(String type) {
|
||||
setClaim(TYPE, type);
|
||||
public void setType(String type) throws ParseException {
|
||||
if(type == null) {
|
||||
throw new NullPointerException("JWT header type value must not be null");
|
||||
}
|
||||
setClaim(TYPE, Type.parse(type));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package org.mitre.jwt.model;
|
||||
|
||||
public enum Type {
|
||||
|
||||
/**
|
||||
* Type ({@code typ}) parameter indicating a JWT.
|
||||
*
|
||||
* <p>Corresponds to the follwoing {@code typ} values:
|
||||
*
|
||||
* <ul>
|
||||
* <li>"JWT"
|
||||
* <li>"urn:ietf:params:oauth:token-type:jwt"
|
||||
* </ul>
|
||||
*/
|
||||
JWT,
|
||||
|
||||
|
||||
/**
|
||||
* Type ({@code typ}) parameter indicating a nested JWS.
|
||||
*
|
||||
* <p>Corresponds to the following {@code typ} value:
|
||||
*
|
||||
* <ul>
|
||||
* <li>"JWS"
|
||||
* </ul>
|
||||
*/
|
||||
JWS,
|
||||
|
||||
|
||||
/**
|
||||
* Type ({@code typ}) parameter indicating a nested JWE.
|
||||
*
|
||||
* <p>Corresponds to the follwoing {@code typ} value:
|
||||
*
|
||||
* <ul>
|
||||
* <li>"JWE"
|
||||
* </ul>
|
||||
*/
|
||||
JWE;
|
||||
|
||||
|
||||
/**
|
||||
* Parses the specified type string (case sensitive).
|
||||
*
|
||||
* <p>Note that both "JWT" and
|
||||
* "urn:ietf:params:oauth:token-type:jwt" resolve to
|
||||
* {@link #JWT}.
|
||||
*
|
||||
* @param s The string to parse.
|
||||
*
|
||||
* @throws java.text.ParseException If the string couldn't be
|
||||
* parsed to a supported JWT
|
||||
* header type.
|
||||
*/
|
||||
public static Type parse(final String s)
|
||||
throws java.text.ParseException {
|
||||
|
||||
if (s == null)
|
||||
throw new NullPointerException("The parsed JWT header \"typ\" value must not be null");
|
||||
|
||||
if (s.equals("JWT") || s.equals("urn:ietf:params:oauth:token-type:jwt"))
|
||||
return JWT;
|
||||
|
||||
if (s.equals("JWS"))
|
||||
return JWS;
|
||||
|
||||
if (s.equals("JWE"))
|
||||
return JWE;
|
||||
|
||||
throw new java.text.ParseException("Unsupported JWT header \"typ\" value: " + s, 0);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@ import javax.crypto.Cipher;
|
|||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
|
||||
import org.easymock.internal.matchers.GreaterThan;
|
||||
import org.junit.After;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
|
@ -64,22 +63,26 @@ public class RsaEncrypterDecrypterTest {
|
|||
//read in header and plaintext from files
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject jweHeaderObject = parser.parse(new BufferedReader(new InputStreamReader(jweHeaderUrl.openStream()))).getAsJsonObject();
|
||||
//create jwe based on header and plaintext
|
||||
Jwe jwe = new Jwe(new JweHeader(jweHeaderObject), null, jwePlaintextString.getBytes(), null);
|
||||
//generate key pair. this will be passed in from the user
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(4096);
|
||||
KeyPair pair = keyGen.generateKeyPair();
|
||||
PublicKey publicKey = pair.getPublic();
|
||||
PrivateKey privateKey = pair.getPrivate();
|
||||
//create jwe based on header and plaintext
|
||||
Jwe jwe = new Jwe(new JweHeader(jweHeaderObject), null, jwePlaintextString.getBytes(), null);
|
||||
//encrypt
|
||||
RsaEncrypter rsaEncrypter = new RsaEncrypter();
|
||||
jwe = rsaEncrypter.encryptAndSign(jwe, publicKey);
|
||||
rsaEncrypter.setPublicKey(publicKey);
|
||||
rsaEncrypter.setPrivateKey(privateKey);
|
||||
jwe = rsaEncrypter.encryptAndSign(jwe);
|
||||
|
||||
//decrypt
|
||||
RsaDecrypter rsaDecrypter = new RsaDecrypter();
|
||||
rsaDecrypter.setPublicKey(publicKey);
|
||||
rsaDecrypter.setPrivateKey(privateKey);
|
||||
String encryptedJweString = jwe.toString();
|
||||
jwe = rsaDecrypter.decrypt(encryptedJweString, privateKey);
|
||||
jwe = rsaDecrypter.decrypt(encryptedJweString);
|
||||
|
||||
String jweDecryptedCleartext = new String(jwe.getCiphertext());
|
||||
//test ALL THE THINGS
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.security.PublicKey;
|
|||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.RSAPrivateKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.bouncycastle.jce.X509Principal;
|
||||
|
@ -57,7 +58,12 @@ public class JwtTest {
|
|||
@Test
|
||||
public void testGenerateHmacSignature() {
|
||||
Jwt jwt = new Jwt();
|
||||
jwt.getHeader().setType("JWT");
|
||||
try {
|
||||
jwt.getHeader().setType("JWT");
|
||||
} catch (ParseException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
jwt.getHeader().setAlgorithm("HS256");
|
||||
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
|
||||
jwt.getClaims().setIssuer("joe");
|
||||
|
|
Loading…
Reference in New Issue