updated encrypter/decrypter to store keys as member variables rather than to pass them in

pull/128/head
Mike Derryberry 2012-07-31 10:33:18 -04:00
parent 61c7231d9a
commit 95dcb10472
7 changed files with 75 additions and 24 deletions

View File

@ -2,7 +2,6 @@ package org.mitre.jwt.encryption;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
@ -13,11 +12,11 @@ import org.mitre.jwe.model.Jwe;
public interface JweDecrypter { 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[] 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;
} }

View File

@ -3,7 +3,6 @@ package org.mitre.jwt.encryption;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
@ -19,11 +18,11 @@ import com.google.gson.JsonSyntaxException;
public interface JweEncrypter { 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 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; public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException;

View File

@ -2,8 +2,9 @@ package org.mitre.jwt.encryption.impl;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -20,8 +21,11 @@ import org.mitre.jwt.encryption.JweAlgorithms;
public class RsaDecrypter extends AbstractJweDecrypter { public class RsaDecrypter extends AbstractJweDecrypter {
private PublicKey publicKey;
private PrivateKey privateKey;
@Override @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); Jwe jwe = Jwe.parse(encryptedJwe);
@ -29,7 +33,7 @@ public class RsaDecrypter extends AbstractJweDecrypter {
if(alg.equals("RSA1_5") || alg.equals("RSA-OAEP") || alg.equals("ECDH-ES") || alg.equals("A128KW") || alg.equals("A256KW")) { 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 //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 //generation of cek and cik
byte[] contentEncryptionKey = null; byte[] contentEncryptionKey = null;
@ -75,11 +79,11 @@ public class RsaDecrypter extends AbstractJweDecrypter {
} }
@Override @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")){ if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
Cipher cipher = Cipher.getInstance("RSA"); Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey); cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
byte[] contentMasterKey = cipher.doFinal(jwe.getEncryptedKey()); byte[] contentMasterKey = cipher.doFinal(jwe.getEncryptedKey());
return contentMasterKey; return contentMasterKey;
@ -89,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;
}
} }

View File

@ -2,8 +2,9 @@ package org.mitre.jwt.encryption.impl;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.util.Random; import java.util.Random;
@ -22,7 +23,10 @@ import org.mitre.jwt.signer.impl.HmacSigner;
public class RsaEncrypter extends AbstractJweEncrypter { public class RsaEncrypter extends AbstractJweEncrypter {
public Jwe encryptAndSign(Jwe jwe, Key publicKey) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException { private PublicKey publicKey;
private PrivateKey privateKey;
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
String alg = jwe.getHeader().getAlgorithm(); String alg = jwe.getHeader().getAlgorithm();
String integrityAlg = jwe.getHeader().getIntegrity(); String integrityAlg = jwe.getHeader().getIntegrity();
@ -48,7 +52,7 @@ public class RsaEncrypter extends AbstractJweEncrypter {
//encrypt claims and cmk to get ciphertext and encrypted key //encrypt claims and cmk to get ciphertext and encrypted key
jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey)); jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey));
jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey, publicKey)); jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey));
//Signer must be hmac //Signer must be hmac
if(integrityAlg.equals("HS256") || integrityAlg.equals("HS384") || integrityAlg.equals("HS512")){ if(integrityAlg.equals("HS256") || integrityAlg.equals("HS384") || integrityAlg.equals("HS512")){
@ -67,12 +71,12 @@ public class RsaEncrypter extends AbstractJweEncrypter {
return jwe; 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")){ if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
Cipher cipher = Cipher.getInstance("RSA"); Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey); cipher.init(Cipher.ENCRYPT_MODE, getPublicKey());
byte[] encryptedKey = cipher.doFinal(contentMasterKey); byte[] encryptedKey = cipher.doFinal(contentMasterKey);
return encryptedKey; return encryptedKey;
@ -109,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;
}
} }

View File

@ -38,6 +38,8 @@ import com.google.gson.JsonPrimitive;
*/ */
public class ClaimSet { public class ClaimSet {
private String jsonString;
// the LinkedHashMap preserves insertion order // the LinkedHashMap preserves insertion order
private Map<String, Object> claims = new LinkedHashMap<String, Object>(); private Map<String, Object> claims = new LinkedHashMap<String, Object>();
@ -94,6 +96,7 @@ public class ClaimSet {
* Set an extension claim * Set an extension claim
*/ */
public void setClaim(String key, Object value) { public void setClaim(String key, Object value) {
jsonString = null;
claims.put(key, value); claims.put(key, value);
} }
@ -101,6 +104,7 @@ public class ClaimSet {
* Set a primitive claim * Set a primitive claim
*/ */
public void setClaim(String key, JsonPrimitive prim) { public void setClaim(String key, JsonPrimitive prim) {
jsonString = null;
if (prim == null) { if (prim == null) {
// in case we get here with a primitive null // in case we get here with a primitive null
claims.put(key, prim); claims.put(key, prim);
@ -111,6 +115,7 @@ public class ClaimSet {
} else if (prim.isString()) { } else if (prim.isString()) {
claims.put(key, prim.getAsString()); claims.put(key, prim.getAsString());
} }
} }
/** /**
@ -203,4 +208,11 @@ public class ClaimSet {
loadFromJsonObject(json); loadFromJsonObject(json);
} }
public String toString() {
if(jsonString == null) {
jsonString = this.getAsJsonObject().toString();
}
return jsonString;
}
} }

View File

@ -22,7 +22,6 @@ import org.apache.commons.codec.binary.Base64;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gson.JsonObject;
public class Jwt { 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. * The signature base of a JWT is the header in Base64, a period ".", and the claims in Base64.
*/ */
public String getSignatureBase() { public String getSignatureBase() {
JsonObject h = header.getAsJsonObject();
JsonObject c = claims.getAsJsonObject();
String h64 = new String(Base64.encodeBase64URLSafe(h.toString().getBytes())); String h64 = new String(Base64.encodeBase64URLSafe(header.toString().getBytes()));
String c64 = new String(Base64.encodeBase64URLSafe(c.toString().getBytes())); String c64 = new String(Base64.encodeBase64URLSafe(claims.toString().getBytes()));
return h64 + "." + c64; return h64 + "." + c64;
} }

View File

@ -73,12 +73,16 @@ public class RsaEncrypterDecrypterTest {
Jwe jwe = new Jwe(new JweHeader(jweHeaderObject), null, jwePlaintextString.getBytes(), null); Jwe jwe = new Jwe(new JweHeader(jweHeaderObject), null, jwePlaintextString.getBytes(), null);
//encrypt //encrypt
RsaEncrypter rsaEncrypter = new RsaEncrypter(); RsaEncrypter rsaEncrypter = new RsaEncrypter();
jwe = rsaEncrypter.encryptAndSign(jwe, publicKey); rsaEncrypter.setPublicKey(publicKey);
rsaEncrypter.setPrivateKey(privateKey);
jwe = rsaEncrypter.encryptAndSign(jwe);
//decrypt //decrypt
RsaDecrypter rsaDecrypter = new RsaDecrypter(); RsaDecrypter rsaDecrypter = new RsaDecrypter();
rsaDecrypter.setPublicKey(publicKey);
rsaDecrypter.setPrivateKey(privateKey);
String encryptedJweString = jwe.toString(); String encryptedJweString = jwe.toString();
jwe = rsaDecrypter.decrypt(encryptedJweString, privateKey); jwe = rsaDecrypter.decrypt(encryptedJweString);
String jweDecryptedCleartext = new String(jwe.getCiphertext()); String jweDecryptedCleartext = new String(jwe.getCiphertext());
//test ALL THE THINGS //test ALL THE THINGS