updated encrypter and decrypter to use enum class rather than fragile parsing
parent
5f80ebc89a
commit
61c7231d9a
|
@ -1,5 +1,7 @@
|
|||
package org.mitre.jwt.encryption;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
public enum JweAlgorithms {
|
||||
|
||||
//Key Derivation Function Values
|
||||
|
@ -19,5 +21,19 @@ public enum JweAlgorithms {
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ 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 {
|
||||
|
@ -33,35 +33,16 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
|||
|
||||
//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 +59,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());
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ 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 {
|
||||
|
@ -31,10 +32,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);
|
||||
|
@ -96,11 +96,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;
|
||||
|
|
|
@ -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,14 +63,14 @@ 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);
|
||||
|
|
Loading…
Reference in New Issue