tests for encryption/decryption done

pull/105/head
Mike Derryberry 2012-07-13 14:28:51 -04:00
parent 88a052019a
commit 13e0a7c4bb
9 changed files with 51 additions and 74 deletions

View File

@ -43,7 +43,6 @@ public class Jwe extends Jwt {
public Jwe(String headerBase64, String encryptedKeyBase64, String cipherTextBase64, String integrityValueBase64) {
byte[] decodedEncryptedKey = Base64.decodeBase64(encryptedKeyBase64.getBytes());
byte[] decodedCipherText = Base64.decodeBase64(cipherTextBase64.getBytes());
String decodedIntegrityValue = new String(Base64.decodeBase64(integrityValueBase64));
this.header = new JweHeader(headerBase64);
this.encryptedKey = decodedEncryptedKey;
this.ciphertext = decodedCipherText;

View File

@ -8,16 +8,14 @@ public abstract class AbstractJweDecrypter implements JwtDecrypter {
long MAX_HASH_INPUTLEN = Long.MAX_VALUE;
long UNSIGNED_INT_MAX_VALUE = 4294967395L;
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) {
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256"); //TODO: should figure out this getInstance itself, not always 256
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//HUGE DISCLAIMER: this won't work on windows machines that don't have jce unlimited security files installed.
//without it, keys can't be over 128 bit in length, and SHA-128 doesn't work for message digest.
//this is what it should be
md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen));
keyDataLen = keyDataLen / 8;
byte[] key = new byte[keyDataLen];

View File

@ -8,9 +8,12 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
public MessageDigest md;
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException {
//TODO: make this work for any key size
md = MessageDigest.getInstance("SHA-256");
//HUGE DISCLAIMER: this won't work on windows machines that don't have jce unlimited security files installed.
//without it, keys can't be over 128 bit in length, and SHA-128 doesn't work for message digest.
//this is what it should be
md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen));
long MAX_HASH_INPUTLEN = Long.MAX_VALUE;
long UNSIGNED_INT_MAX_VALUE = 4294967395L;

View File

@ -38,16 +38,14 @@ public class RsaDecrypter extends AbstractJweDecrypter {
//generation of cek and cik
byte[] contentEncryptionKey = null;
byte[] contentIntegrityKey = null;
//check whether the key length is 128 or 256
if(jwe.getHeader().getEncryptionMethod().equals("A128CBC") || jwe.getHeader().getEncryptionMethod().equals("A128GCM")){
contentEncryptionKey = generateContentKey(jwe.getEncryptedKey(), 128, new String("Encryption").getBytes());
contentIntegrityKey = generateContentKey(jwe.getEncryptedKey(), 128, new String("Integrity").getBytes());
} else if(jwe.getHeader().getEncryptionMethod().equals("A256CBC") || jwe.getHeader().getEncryptionMethod().equals("A256GCM")){
contentEncryptionKey = generateContentKey(jwe.getEncryptedKey(), 256, new String("Encryption").getBytes());
contentIntegrityKey = generateContentKey(jwe.getEncryptedKey(), 256, new String("Integrity").getBytes());
} else {
throw new IllegalArgumentException(jwe.getHeader().getEncryptionMethod() + " is not a valid encryption method");
}
//check what the key length is
String encMethod = jwe.getHeader().getEncryptionMethod();
char[] array = encMethod.toCharArray();
String keyBitLengthString = String.copyValueOf(array, 1, 3);
int keyBitLength = Integer.parseInt(keyBitLengthString);
//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));
@ -83,12 +81,12 @@ public class RsaDecrypter extends AbstractJweDecrypter {
String encMethod = jwe.getHeader().getEncryptionMethod();
if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC") || encMethod.equals("A128GCM") || encMethod.equals("A128GCM")) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cek, "AES"), new IvParameterSpec(iv));
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cek, "AES"), new IvParameterSpec(iv));
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
return clearText;
return clearText;
} else {
throw new IllegalArgumentException(jwe.getHeader().getAlgorithm() + " is not an implemented algorithm");

View File

@ -35,28 +35,22 @@ public class RsaEncrypter extends AbstractJweEncrypter {
//generate random content master key
byte[] contentMasterKey = new byte[128];
//check what the key length is
String encMethod = jwe.getHeader().getEncryptionMethod();
char[] array = encMethod.toCharArray();
String keyBitLengthString = String.copyValueOf(array, 1, 3);
int keyBitLength = Integer.parseInt(keyBitLengthString);
byte[] contentMasterKey = new byte[keyBitLength];
new Random().nextBytes(contentMasterKey);
//generate CEK and CIK
byte[] contentEncryptionKey = null;
byte[] contentIntegrityKey = null;
//check what the key length is
if(jwe.getHeader().getEncryptionMethod().equals("A128CBC") || jwe.getHeader().getEncryptionMethod().equals("A128GCM")){
contentEncryptionKey = generateContentKey(contentMasterKey, 128, "Encryption".getBytes());
contentIntegrityKey = generateContentKey(contentMasterKey, 128, "Integrity".getBytes());
} else if(jwe.getHeader().getEncryptionMethod().equals("A256CBC") || jwe.getHeader().getEncryptionMethod().equals("A256GCM")){
contentEncryptionKey = generateContentKey(contentMasterKey, 256, new String("Encryption").getBytes());
contentIntegrityKey = generateContentKey(contentMasterKey, 256, new String("Integrity").getBytes());
} else if(jwe.getHeader().getEncryptionMethod().equals("A384CBC") || jwe.getHeader().getEncryptionMethod().equals("A384GCM")){
contentEncryptionKey = generateContentKey(contentMasterKey, 384, new String("Encryption").getBytes());
contentIntegrityKey = generateContentKey(contentMasterKey, 384, new String("Integrity").getBytes());
} else if(jwe.getHeader().getEncryptionMethod().equals("A512CBC") || jwe.getHeader().getEncryptionMethod().equals("A512GCM")){
contentEncryptionKey = generateContentKey(contentMasterKey, 512, new String("Encryption").getBytes());
contentIntegrityKey = generateContentKey(contentMasterKey, 512, new String("Integrity").getBytes());
}
//generate cek and cik
contentEncryptionKey = generateContentKey(contentMasterKey, keyBitLength, "Encryption".getBytes());
contentIntegrityKey = generateContentKey(contentMasterKey, keyBitLength, "Integrity".getBytes());
//encrypt claims and cmk to get ciphertext and encrypted key
jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey));
@ -109,7 +103,7 @@ public class RsaEncrypter extends AbstractJweEncrypter {
String encMethod = jwe.getHeader().getEncryptionMethod();
if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC") || encMethod.equals("A128GCM") || encMethod.equals("A128GCM")) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv));
byte[] cipherText = cipher.doFinal(jwe.getCiphertext());

View File

@ -3,12 +3,8 @@ package org.mitre.jwe.encryption.impl;
import static org.junit.Assert.assertEquals;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@ -44,10 +40,7 @@ import com.google.gson.JsonSyntaxException;
public class RsaEncrypterDecrypterTest {
URL jweHeaderUrl = this.getClass().getResource("/jwe/jweHeader");
URL jwePlaintextUrl = this.getClass().getResource("/jwe/jwePlaintext");
URL jweEncryptedUrl = this.getClass().getResource("/jwe/encryptedJwe");
String jweEncryptedUrlString = jweEncryptedUrl.toString();
File jweEncryptedFile = new File(jweEncryptedUrlString);
String jwePlaintextString = new String("Why couldn't the bike move? It was two tired.");
@Before
public void setUp(){
@ -59,40 +52,33 @@ public class RsaEncrypterDecrypterTest {
@Test
public void encryptDecryptTest() throws JsonIOException, JsonSyntaxException, IOException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
//read in header and plaintext from files
JsonParser parser = new JsonParser();
JsonObject jweHeaderObject = parser.parse(new BufferedReader(new InputStreamReader(jweHeaderUrl.openStream()))).getAsJsonObject();
String jwePlaintextString = parser.parse(new BufferedReader(new InputStreamReader(jwePlaintextUrl.openStream()))).toString();
//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(2048);
keyGen.initialize(4096);
KeyPair pair = keyGen.generateKeyPair();
PublicKey publicKey = pair.getPublic();
PrivateKey privateKey = pair.getPrivate();
//encrypt
RsaEncrypter rsaEncrypter = new RsaEncrypter();
jwe = rsaEncrypter.encryptAndSign(jwe, publicKey);
//put encrypted jwe in text file to then be decrypted
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("C:/Users/derryberry/projects/OpenID-Connect-Java-Spring-Server-2/openid-connect-common/target/test-classes/jwe/encryptedJwe")));
out.println(jwe.toString());
out.close();
String jweEncryptedString = parser.parse(new BufferedReader(new InputStreamReader(jweEncryptedUrl.openStream()))).toString();
jweEncryptedString = jweEncryptedString.replaceAll("^\"|\"$", "");
assertEquals(jwe.toString(), jweEncryptedString);
//decrypt
RsaDecrypter rsaDecrypter = new RsaDecrypter();
String encryptedJweString = jwe.toString();
jwe = rsaDecrypter.decrypt(encryptedJweString, privateKey);
assertEquals(new String(jwe.getCiphertext()), jwePlaintextString);
assertEquals(jwe.getHeader().getAlgorithm(), "RSA1_5");
assertEquals(jwe.getHeader().getEncryptionMethod(), "A128CBC");
assertEquals(jwe.getHeader().getIntegrity(), "HS256");
assertEquals(jwe.getHeader().getInitializationVector(), "AxY8DCtDaGlsbGljb3RoZQ");
String jweDecryptedCleartext = new String(jwe.getCiphertext());
//test ALL THE THINGS
assertEquals(jweDecryptedCleartext, jwePlaintextString);
assertEquals(jwe.getHeader().getAlgorithm(), jweHeaderObject.get("alg").getAsString());
assertEquals(jwe.getHeader().getEncryptionMethod(), jweHeaderObject.get("enc").getAsString());
assertEquals(jwe.getHeader().getIntegrity(), jweHeaderObject.get("int").getAsString());
assertEquals(jwe.getHeader().getInitializationVector(), jweHeaderObject.get("iv").getAsString());
}

View File

@ -1 +1 @@
{"alg":"RSA1_5","enc":"A128CBC","int":"HS256","iv":"AxY8DCtDaGlsbGljb3RoZQ"}
{"alg":"RSA1_5","enc":"A256CBC","int":"HS256","iv":"AxY8DCtDaGlsbGljb3RoZQ"}

View File

@ -1 +0,0 @@
"Why couldn't the bike move? It was two tired."