From 5d3d888c3f671e762a8333f6fce41e7d95506264 Mon Sep 17 00:00:00 2001 From: Mike Derryberry Date: Mon, 16 Jul 2012 10:27:02 -0400 Subject: [PATCH] finished testing. fixed MessageDigest problems in generating cek and cik --- .../jwt/encryption/AbstractJweDecrypter.java | 12 +++- .../jwt/encryption/AbstractJweEncrypter.java | 10 +++- .../mitre/jwt/encryption/JwtAlgorithm.java | 60 ------------------- .../jwt/encryption/impl/RsaDecrypter.java | 9 ++- .../jwt/encryption/impl/RsaEncrypter.java | 17 ++---- .../src/test/resources/jwe/jweHeader | 2 +- 6 files changed, 28 insertions(+), 82 deletions(-) delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtAlgorithm.java diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweDecrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweDecrypter.java index 6507c3101..658004c3c 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweDecrypter.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweDecrypter.java @@ -14,9 +14,15 @@ public abstract class AbstractJweDecrypter implements JwtDecrypter { //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)); - + //SHA-128 is not a valid instance, therefore change to 256 + if(keyDataLen == 128){ + md = MessageDigest.getInstance("SHA-256"); + } + //use keyDataLen to determine instance + else { + md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen)); + } + keyDataLen = keyDataLen / 8; byte[] key = new byte[keyDataLen]; int hashLen = md.getDigestLength(); diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java index 4275d392e..ad83bc662 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java @@ -11,8 +11,14 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter { //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)); + //SHA-128 is not a valid instance, therefore change to 256 + if(keyDataLen == 128){ + md = MessageDigest.getInstance("SHA-256"); + } + //Use keyDataLen to determine instance + else { + md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen)); + } long MAX_HASH_INPUTLEN = Long.MAX_VALUE; long UNSIGNED_INT_MAX_VALUE = 4294967395L; diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtAlgorithm.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtAlgorithm.java deleted file mode 100644 index ca5c96ea3..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtAlgorithm.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.mitre.jwt.encryption; - -import org.apache.commons.lang.StringUtils; - -public enum JwtAlgorithm { - - //TODO:Fill in values for each standard name - // RSA - RSA1_5("RSA"), - RSA_OAEP("RSA"), - //EC - ECDH_ES("EC"), - //AES - A128KW("AES"), - A256KW("AES"), - A128CBC("AES"), - A256CBC("AES"), - A128GCM("AES"), - A256GCM("AES"); - - - - /** - * Returns the Algorithm for the name - * - * @param name - * @return - */ - public static JwtAlgorithm getByName(String name) { - for (JwtAlgorithm correspondingType : JwtAlgorithm.values()) { - if (correspondingType.toString().equals(name)) { - return correspondingType; - } - } - - // corresponding type not found - throw new IllegalArgumentException( - "JwtAlgorithm name " + name + " does not have a corresponding JwtAlgorithm: expected one of [" + StringUtils.join(JwtAlgorithm.values(), ", ") + "]"); - } - - private final String standardName; - - /** - * Constructor of JwtAlgorithm - * - * @param standardName - */ - JwtAlgorithm(String standardName) { - this.standardName = standardName; - } - - /** - * Return the Java standard JwtAlgorithm name - * - * @return - */ - public String getStandardName() { - return standardName; - } -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java index 69ddd508a..516b58ba2 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java @@ -73,23 +73,23 @@ public class RsaDecrypter extends AbstractJweDecrypter { } @Override - public byte[] decryptCipherText(Jwe jwe, byte[] cek) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { + public byte[] decryptCipherText(Jwe jwe, byte[] contentEncryptionKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { byte[] iv = new byte[16]; iv = Base64.decodeBase64(jwe.getHeader().getInitializationVector()); String encMethod = jwe.getHeader().getEncryptionMethod(); - if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC") || encMethod.equals("A128GCM") || encMethod.equals("A128GCM")) { + if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC") || encMethod.equals("A128GCM") || encMethod.equals("A256GCM")) { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cek, "AES"), new IvParameterSpec(iv)); + cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv)); byte[] clearText = cipher.doFinal(jwe.getCiphertext()); return clearText; } else { - throw new IllegalArgumentException(jwe.getHeader().getAlgorithm() + " is not an implemented algorithm"); + throw new IllegalArgumentException(jwe.getHeader().getEncryptionMethod() + " is not an implemented encryption method"); } @@ -101,7 +101,6 @@ public class RsaDecrypter extends AbstractJweDecrypter { if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){ Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); - //TODO: Get private key from key store. Placeholder byte[] contentMasterKey = cipher.doFinal(jwe.getEncryptedKey()); return contentMasterKey; diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java index b9bc810ad..a4bcda866 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java @@ -47,7 +47,6 @@ public class RsaEncrypter extends AbstractJweEncrypter { byte[] contentEncryptionKey = null; byte[] contentIntegrityKey = null; - //generate cek and cik contentEncryptionKey = generateContentKey(contentMasterKey, keyBitLength, "Encryption".getBytes()); contentIntegrityKey = generateContentKey(contentMasterKey, keyBitLength, "Integrity".getBytes()); @@ -63,24 +62,23 @@ public class RsaEncrypter extends AbstractJweEncrypter { jwe = (Jwe) hmacSigner.sign(jwe); } else { - throw new IllegalArgumentException(integrityAlg + " is not a valid integrity value algorithm"); + throw new IllegalArgumentException(integrityAlg + " is not a valid integrity value algorithm for signing."); } } else { - throw new IllegalArgumentException(alg + " is not a valid signing algorithm"); + throw new IllegalArgumentException(alg + " is not a valid encrypting algorithm."); } return jwe; } - public byte[] encryptKey(Jwe jwe, byte[] cmk, Key publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + public byte[] encryptKey(Jwe jwe, byte[] contentMasterKey, Key publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - //TODO:Get public key from keystore, for now randomly generate key pair if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){ Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); - byte[] encryptedKey = cipher.doFinal(cmk); + byte[] encryptedKey = cipher.doFinal(contentMasterKey); return encryptedKey; } else { @@ -102,7 +100,7 @@ public class RsaEncrypter extends AbstractJweEncrypter { String encMethod = jwe.getHeader().getEncryptionMethod(); - if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC") || encMethod.equals("A128GCM") || encMethod.equals("A128GCM")) { + if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC") || encMethod.equals("A128GCM") || encMethod.equals("A256GCM")) { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv)); @@ -110,11 +108,8 @@ public class RsaEncrypter extends AbstractJweEncrypter { return cipherText; } else { - throw new IllegalArgumentException(jwe.getHeader().getAlgorithm() + " is not a supported algorithm"); + throw new IllegalArgumentException(jwe.getHeader().getEncryptionMethod() + " is not a supported encryption method"); } } - - - } diff --git a/openid-connect-common/src/test/resources/jwe/jweHeader b/openid-connect-common/src/test/resources/jwe/jweHeader index 296669820..c8566eae5 100644 --- a/openid-connect-common/src/test/resources/jwe/jweHeader +++ b/openid-connect-common/src/test/resources/jwe/jweHeader @@ -1 +1 @@ -{"alg":"RSA1_5","enc":"A256CBC","int":"HS256","iv":"AxY8DCtDaGlsbGljb3RoZQ"} \ No newline at end of file +{"alg":"RSA1_5","enc":"A128CBC","int":"HS384","iv":"AxY8DCtDaGlsbGljb3RoZQ"} \ No newline at end of file