updated encryption/decryption to dynamically get mode for cipher. also made the keyDataLen come from the kdf parameter rather than enc
parent
5d3d888c3f
commit
e380d85ad7
|
@ -1 +0,0 @@
|
||||||
eyJpbnQiOiJIUzI1NiIsIml2IjoiQXhZOERDdERhR2xzYkdsamIzUm9aUSIsImFsZyI6IkhTMjU2IiwiZW5jIjoiQTEyOENCQyJ9.1TWc1U58WUtz6HnRVfFcCFt04dWJivMZmTG3ZeIUKbfWbG6UHsYRNnj1a9LvYpb7DA97j57whfXxxwT9P3ZnCMaeqm_JCmyasocu7ftefELw4BSYcBuIGeiOzZO7mffS4lj5s7N76kV-LXkVIMwjzKom1z1doBqnmV7M5yUCTnxQJ3ao7LYLJI0QiCY5Pcqd.CS8GW8JLnDAF4SEvw2kras0yp50-eIX90Mbn1qKF1cePqG3VWcItEJoPa0FbFbmj.0uQ48_WFcQR-q6IBcs8IG-DquLi17kbeXjqKRANr0Hw
|
|
|
@ -13,15 +13,9 @@ public abstract class AbstractJweDecrypter implements JwtDecrypter {
|
||||||
MessageDigest md = null;
|
MessageDigest md = null;
|
||||||
//HUGE DISCLAIMER: this won't work on windows machines that don't have jce unlimited security files installed.
|
//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.
|
//without it, keys can't be over 128 bit in length, and SHA-128 doesn't work for message digest.
|
||||||
|
|
||||||
//SHA-128 is not a valid instance, therefore change to 256
|
|
||||||
if(keyDataLen == 128){
|
|
||||||
md = MessageDigest.getInstance("SHA-256");
|
|
||||||
}
|
|
||||||
//use keyDataLen to determine instance
|
//use keyDataLen to determine instance
|
||||||
else {
|
md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen));
|
||||||
md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen));
|
|
||||||
}
|
|
||||||
|
|
||||||
keyDataLen = keyDataLen / 8;
|
keyDataLen = keyDataLen / 8;
|
||||||
byte[] key = new byte[keyDataLen];
|
byte[] key = new byte[keyDataLen];
|
||||||
|
|
|
@ -11,14 +11,8 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
//HUGE DISCLAIMER: this won't work on windows machines that don't have jce unlimited security files installed.
|
//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.
|
//without it, keys can't be over 128 bit in length, and SHA-128 doesn't work for message digest.
|
||||||
|
|
||||||
//SHA-128 is not a valid instance, therefore change to 256
|
|
||||||
if(keyDataLen == 128){
|
|
||||||
md = MessageDigest.getInstance("SHA-256");
|
|
||||||
}
|
|
||||||
//Use keyDataLen to determine instance
|
//Use keyDataLen to determine instance
|
||||||
else {
|
md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen));
|
||||||
md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen));
|
|
||||||
}
|
|
||||||
|
|
||||||
long MAX_HASH_INPUTLEN = Long.MAX_VALUE;
|
long MAX_HASH_INPUTLEN = Long.MAX_VALUE;
|
||||||
long UNSIGNED_INT_MAX_VALUE = 4294967395L;
|
long UNSIGNED_INT_MAX_VALUE = 4294967395L;
|
||||||
|
@ -60,5 +54,4 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
byte[] contentEncryptionKey = null;
|
byte[] contentEncryptionKey = null;
|
||||||
byte[] contentIntegrityKey = null;
|
byte[] contentIntegrityKey = null;
|
||||||
//check what the key length is
|
//check what the key length is
|
||||||
String encMethod = jwe.getHeader().getEncryptionMethod();
|
String encMethod = jwe.getHeader().getKeyDerivationFunction();
|
||||||
char[] array = encMethod.toCharArray();
|
char[] array = encMethod.toCharArray();
|
||||||
String keyBitLengthString = String.copyValueOf(array, 1, 3);
|
String keyBitLengthString = new String("" + array[2] + array[3] + array[4]);
|
||||||
int keyBitLength = Integer.parseInt(keyBitLengthString);
|
int keyBitLength = Integer.parseInt(keyBitLengthString);
|
||||||
//generate cek and cik
|
//generate cek and cik
|
||||||
contentEncryptionKey = generateContentKey(jwe.getEncryptedKey(), keyBitLength, "Encryption".getBytes());
|
contentEncryptionKey = generateContentKey(jwe.getEncryptedKey(), keyBitLength, "Encryption".getBytes());
|
||||||
|
@ -79,10 +79,13 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
iv = Base64.decodeBase64(jwe.getHeader().getInitializationVector());
|
iv = Base64.decodeBase64(jwe.getHeader().getInitializationVector());
|
||||||
|
|
||||||
String encMethod = jwe.getHeader().getEncryptionMethod();
|
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") || encMethod.equals("A128GCM") || encMethod.equals("A256GCM")) {
|
if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC")) {
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
String delims = "[8,6]+";
|
||||||
|
String[] mode = encMethod.split(delims);
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/" + mode[1] + "/PKCS5Padding");
|
||||||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv));
|
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv));
|
||||||
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
|
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
//generate random content master key
|
//generate random content master key
|
||||||
|
|
||||||
//check what the key length is
|
//check what the key length is
|
||||||
String encMethod = jwe.getHeader().getEncryptionMethod();
|
String encMethod = jwe.getHeader().getKeyDerivationFunction();
|
||||||
char[] array = encMethod.toCharArray();
|
char[] array = encMethod.toCharArray();
|
||||||
String keyBitLengthString = String.copyValueOf(array, 1, 3);
|
String keyBitLengthString = new String("" + array[2] + array[3] + array[4]);
|
||||||
int keyBitLength = Integer.parseInt(keyBitLengthString);
|
int keyBitLength = Integer.parseInt(keyBitLengthString);
|
||||||
|
|
||||||
byte[] contentMasterKey = new byte[keyBitLength];
|
byte[] contentMasterKey = new byte[keyBitLength];
|
||||||
|
@ -99,10 +99,13 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
}
|
}
|
||||||
|
|
||||||
String encMethod = jwe.getHeader().getEncryptionMethod();
|
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") || encMethod.equals("A128GCM") || encMethod.equals("A256GCM")) {
|
if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC")) {
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
String delims = "[8,6]+";
|
||||||
|
String[] mode = encMethod.split(delims);
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/" + mode[1] + "/PKCS5Padding");
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv));
|
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv));
|
||||||
byte[] cipherText = cipher.doFinal(jwe.getCiphertext());
|
byte[] cipherText = cipher.doFinal(jwe.getCiphertext());
|
||||||
return cipherText;
|
return cipherText;
|
||||||
|
|
|
@ -57,14 +57,15 @@ public abstract class AbstractJwtSigner implements JwtSigner {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Jwt sign(Jwt jwt) throws NoSuchAlgorithmException {
|
public Jwt sign(Jwt jwt) throws NoSuchAlgorithmException {
|
||||||
//TODO: this check changes the algorithm param of a jwe to the int param. not sure why?
|
|
||||||
|
//TODO: need a seperate check for Jwe. As is, it will change the alg param to be the enc param
|
||||||
/*if (!Objects.equal(algorithm, jwt.getHeader().getAlgorithm())) {
|
/*if (!Objects.equal(algorithm, jwt.getHeader().getAlgorithm())) {
|
||||||
// algorithm type doesn't match
|
// algorithm type doesn't match
|
||||||
// TODO: should this be an error or should we just fix it in the incoming jwt?
|
// TODO: should this be an error or should we just fix it in the incoming jwt?
|
||||||
// for now, we fix the Jwt
|
// for now, we fix the Jwt
|
||||||
jwt.getHeader().setAlgorithm(algorithm);
|
jwt.getHeader().setAlgorithm(algorithm);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
String sig = generateSignature(jwt.getSignatureBase());
|
String sig = generateSignature(jwt.getSignatureBase());
|
||||||
|
|
||||||
jwt.setSignature(sig);
|
jwt.setSignature(sig);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"alg":"RSA1_5","enc":"A128CBC","int":"HS384","iv":"AxY8DCtDaGlsbGljb3RoZQ"}
|
{"alg":"RSA1_5","enc":"A256CBC","int":"HS384","iv":"AxY8DCtDaGlsbGljb3RoZQ","kdf":"CS256"}
|
Loading…
Reference in New Issue