updated encryption to generate cek and cik through key derivation. also fixed signers to use afterPropertiesSet()
parent
7e7cd4f480
commit
d86ee2329b
|
@ -6,10 +6,18 @@ import org.apache.commons.codec.binary.Base64;
|
||||||
import org.mitre.jwt.model.Jwt;
|
import org.mitre.jwt.model.Jwt;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return the canonical encoded string of this JWE, the header in Base64, a period ".", the encrypted key in Base64, a period ".",
|
||||||
|
* the ciphertext in Base64, a period ".", and the signature, or integrity value, in Base64.
|
||||||
|
|
||||||
|
* @author DERRYBERRY
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class Jwe extends Jwt {
|
public class Jwe extends Jwt {
|
||||||
|
|
||||||
private JweHeader header;
|
private JweHeader header;
|
||||||
|
@ -18,20 +26,30 @@ public class Jwe extends Jwt {
|
||||||
|
|
||||||
private byte[] ciphertext;
|
private byte[] ciphertext;
|
||||||
|
|
||||||
private String signature;
|
|
||||||
|
|
||||||
public Jwe() {
|
public Jwe() {
|
||||||
|
super();
|
||||||
this.header = new JweHeader();
|
this.header = new JweHeader();
|
||||||
this.encryptedKey = null;
|
this.encryptedKey = null;
|
||||||
this.ciphertext = null;
|
this.ciphertext = null;
|
||||||
this.signature = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jwe(JweHeader header, byte[] encryptedKey, byte[] ciphertext, String integrityValue) {
|
public Jwe(JweHeader header, byte[] encryptedKey, byte[] ciphertext, String integrityValue) {
|
||||||
|
super(null, null, integrityValue);
|
||||||
this.header = header;
|
this.header = header;
|
||||||
this.encryptedKey = encryptedKey;
|
this.encryptedKey = encryptedKey;
|
||||||
this.ciphertext = ciphertext;
|
this.ciphertext = ciphertext;
|
||||||
this.signature = integrityValue;
|
}
|
||||||
|
|
||||||
|
public Jwe(String headerBase64, String encryptedKeyBase64, String cipherTextBase64, String integrityValueBase64) {
|
||||||
|
super(null, null, new String(Base64.decodeBase64(integrityValueBase64)));
|
||||||
|
String decodedHeader = new String(Base64.decodeBase64(headerBase64));
|
||||||
|
String decodedEncryptedKey = new String(Base64.decodeBase64(encryptedKeyBase64));
|
||||||
|
String decodedCipherText = new String(Base64.decodeBase64(cipherTextBase64));
|
||||||
|
String decodedIntegrityValue = new String(Base64.decodeBase64(integrityValueBase64));
|
||||||
|
this.header = new JweHeader(decodedHeader);
|
||||||
|
this.encryptedKey = decodedEncryptedKey.getBytes();
|
||||||
|
this.ciphertext = decodedCipherText.getBytes();
|
||||||
|
setSignature(decodedIntegrityValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JweHeader getHeader() {
|
public JweHeader getHeader() {
|
||||||
|
@ -58,24 +76,6 @@ public class Jwe extends Jwt {
|
||||||
this.ciphertext = ciphertext;
|
this.ciphertext = ciphertext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSignature(String signature) {
|
|
||||||
this.signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the canonical encoded string of this JWE, the header in Base64, a period ".", the encrypted key in Base64, a period ".",
|
|
||||||
* the ciphertext in Base64, a period ".", and the signature, or integrity value, in Base64.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getSignatureBase() + "." + Strings.nullToEmpty(this.signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSignatureBase() {
|
public String getSignatureBase() {
|
||||||
JsonObject h = header.getAsJsonObject();
|
JsonObject h = header.getAsJsonObject();
|
||||||
|
@ -109,8 +109,7 @@ public class Jwe extends Jwt {
|
||||||
String c64 = parts.get(2);
|
String c64 = parts.get(2);
|
||||||
String i64 = parts.get(3);
|
String i64 = parts.get(3);
|
||||||
|
|
||||||
Jwe jwe = new Jwe(new JweHeader(h64), e64.getBytes(), c64.getBytes(), i64);
|
Jwe jwe = new Jwe(h64, e64, c64, i64);
|
||||||
//Jwe jwe = new Jwe(new JweHeader(h64), e64.getBytes(), new ClaimSet(c64), i64);
|
|
||||||
|
|
||||||
return jwe;
|
return jwe;
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,11 @@
|
||||||
package org.mitre.jwt.encryption;
|
package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.Key;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class AbstractJweDecrypter implements JwtDecrypter {
|
public abstract class AbstractJweDecrypter implements JwtDecrypter {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private PrivateKey privateKey;
|
protected PrivateKey privateKey;
|
||||||
|
|
||||||
private PublicKey publicKey;
|
private PublicKey publicKey;
|
||||||
|
|
||||||
|
@ -37,68 +24,4 @@ public abstract class AbstractJweDecrypter implements JwtDecrypter {
|
||||||
public void setPublicKey(PublicKey publicKey) {
|
public void setPublicKey(PublicKey publicKey) {
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String decryptCipherText(Jwe jwe, Key cek) {
|
|
||||||
Cipher cipher;
|
|
||||||
String clearTextString = null;
|
|
||||||
try {
|
|
||||||
|
|
||||||
cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, cek);
|
|
||||||
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
|
|
||||||
clearTextString = new String(clearText);
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return clearTextString;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] decryptEncryptionKey(Jwe jwe) {
|
|
||||||
Cipher cipher;
|
|
||||||
byte[] contentMasterKey = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);//TODO: Get private key from key store. Placeholder
|
|
||||||
contentMasterKey = cipher.doFinal(jwe.getEncryptedKey());
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return contentMasterKey;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,17 @@
|
||||||
package org.mitre.jwt.encryption;
|
package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
import java.security.MessageDigest;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.KeyPair;
|
|
||||||
import java.security.KeyPairGenerator;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.security.interfaces.RSAPublicKey;
|
|
||||||
import java.security.spec.InvalidParameterSpecException;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
|
||||||
import org.springframework.security.crypto.codec.Base64;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
|
|
||||||
private byte[] encryptedKey;
|
protected byte[] encryptedKey;
|
||||||
|
|
||||||
private byte[] cipherText;
|
protected byte[] cipherText;
|
||||||
|
|
||||||
private RSAPublicKey publicKey;
|
protected PublicKey publicKey;
|
||||||
|
|
||||||
|
public MessageDigest md;
|
||||||
|
|
||||||
public byte[] getEncryptecKey() {
|
public byte[] getEncryptecKey() {
|
||||||
return encryptedKey;
|
return encryptedKey;
|
||||||
|
@ -43,93 +28,48 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
public void setCipherText(byte[] cipherText) {
|
public void setCipherText(byte[] cipherText) {
|
||||||
this.cipherText = cipherText;
|
this.cipherText = cipherText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) {
|
||||||
|
|
||||||
|
long MAX_HASH_INPUTLEN = Long.MAX_VALUE;
|
||||||
public byte[] encryptKey(Jwe jwe){
|
long UNSIGNED_INT_MAX_VALUE = 4294967395L;
|
||||||
|
|
||||||
//generate random content master key
|
keyDataLen = keyDataLen / 8;
|
||||||
PublicKey contentMasterKey = null;
|
byte[] key = new byte[keyDataLen];
|
||||||
|
int hashLen = md.getDigestLength();
|
||||||
try {
|
int reps = keyDataLen / hashLen;
|
||||||
|
if (reps > UNSIGNED_INT_MAX_VALUE) {
|
||||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(jwe.getHeader().getAlgorithm());
|
throw new IllegalArgumentException("Key derivation failed");
|
||||||
SecureRandom random = SecureRandom.getInstance(jwe.getHeader().getAlgorithm());
|
}
|
||||||
keyGen.initialize(1024, random);
|
int counter = 1;
|
||||||
KeyPair pair = keyGen.generateKeyPair();
|
byte[] counterInBytes = intToFourBytes(counter);
|
||||||
contentMasterKey = pair.getPublic();
|
if ((counterInBytes.length + cmk.length + type.length) * 8 > MAX_HASH_INPUTLEN) {
|
||||||
|
throw new IllegalArgumentException("Key derivation failed");
|
||||||
} catch (NoSuchAlgorithmException e1) {
|
}
|
||||||
// TODO Auto-generated catch block
|
for (int i = 0; i <= reps; i++) {
|
||||||
e1.printStackTrace();
|
md.reset();
|
||||||
}
|
md.update(intToFourBytes(i + 1));
|
||||||
|
md.update(cmk);
|
||||||
|
md.update(type);
|
||||||
//TODO:Get public key from keystore, currently null
|
byte[] hash = md.digest();
|
||||||
Cipher cipher;
|
if (i < reps) {
|
||||||
try {
|
System.arraycopy(hash, 0, key, hashLen * i, hashLen);
|
||||||
cipher = Cipher.getInstance("RSA");
|
} else {
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
System.arraycopy(hash, 0, key, hashLen * i, keyDataLen % hashLen);
|
||||||
encryptedKey = cipher.doFinal(contentMasterKey.getEncoded());
|
}
|
||||||
|
}
|
||||||
} catch (NoSuchAlgorithmException e) {
|
return key;
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return encryptedKey;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encryptClaims(Jwe jwe, Key cek) {
|
public byte[] intToFourBytes(int i) {
|
||||||
|
byte[] res = new byte[4];
|
||||||
Cipher cipher;
|
res[0] = (byte) (i >>> 24);
|
||||||
try {
|
res[1] = (byte) ((i >>> 16) & 0xFF);
|
||||||
cipher = Cipher.getInstance("RSA");
|
res[2] = (byte) ((i >>> 8) & 0xFF);
|
||||||
|
res[3] = (byte) (i & 0xFF);
|
||||||
//TODO: generated the iv, but not sure how to use it to encrypt?
|
return res;
|
||||||
IvParameterSpec spec = cipher.getParameters().getParameterSpec(IvParameterSpec.class);
|
}
|
||||||
byte[] iv = spec.getIV();
|
|
||||||
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, cek);
|
|
||||||
cipherText = cipher.doFinal(jwe.getClaims().toString().getBytes());
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidParameterSpecException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return cipherText;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
public enum AlgorithmLength {
|
||||||
|
//TODO:Fill in values for each standard name
|
||||||
|
// RSA
|
||||||
|
A128CBC("128"),
|
||||||
|
A256CBC("256"),
|
||||||
|
A128GCM("128"),
|
||||||
|
A256GCM("256");
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Algorithm for the name
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static AlgorithmLength getByName(String name) {
|
||||||
|
for (AlgorithmLength correspondingType : AlgorithmLength.values()) {
|
||||||
|
if (correspondingType.toString().equals(name)) {
|
||||||
|
return correspondingType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// corresponding type not found
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"AlgorithmLength name " + name + " does not have a corresponding AlgorithmLength: expected one of [" + StringUtils.join(AlgorithmLength.values(), ", ") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String standardName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of AlgorithmLength
|
||||||
|
*
|
||||||
|
* @param standardName
|
||||||
|
*/
|
||||||
|
AlgorithmLength(String standardName) {
|
||||||
|
this.standardName = standardName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Java standard Algorithm Length
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getStandardName() {
|
||||||
|
return standardName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
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_OAEP(""),
|
||||||
|
//EC
|
||||||
|
ECDH_ES(""),
|
||||||
|
//AES
|
||||||
|
A128KW(""),
|
||||||
|
A256KW(""),
|
||||||
|
A128GCM(""),
|
||||||
|
A256GCM("");
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,10 +8,14 @@ import org.mitre.jwe.model.Jwe;
|
||||||
|
|
||||||
public interface JwtEncrypter {
|
public interface JwtEncrypter {
|
||||||
|
|
||||||
public byte[] encryptKey(Jwe jwe);
|
public byte[] encryptKey(Jwe jwe, Key cmk);
|
||||||
|
|
||||||
public byte[] encryptClaims(Jwe jwe, Key cik);
|
public byte[] encryptClaims(Jwe jwe, byte[] cik);
|
||||||
|
|
||||||
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException;
|
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type);
|
||||||
|
|
||||||
|
public byte[] intToFourBytes(int i);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
package org.mitre.jwt.encryption.impl;
|
|
||||||
|
|
||||||
import java.security.KeyPair;
|
|
||||||
import java.security.KeyPairGenerator;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
|
||||||
import org.mitre.jwe.model.JweHeader;
|
|
||||||
import org.mitre.jwt.encryption.AbstractJweDecrypter;
|
|
||||||
import org.mitre.jwt.signer.impl.HmacSigner;
|
|
||||||
|
|
||||||
|
|
||||||
public class Decrypter extends AbstractJweDecrypter {
|
|
||||||
|
|
||||||
private Jwe jwe;
|
|
||||||
|
|
||||||
public Decrypter(Jwe jwe) {
|
|
||||||
setJwe(jwe);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jwe getJwe() {
|
|
||||||
return jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJwe(Jwe jwe) {
|
|
||||||
this.jwe = jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Jwe decrypt(String encryptedJwe) {
|
|
||||||
|
|
||||||
Jwe jwe = Jwe.parse(encryptedJwe);
|
|
||||||
|
|
||||||
String alg = jwe.getHeader().getAlgorithm();
|
|
||||||
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
|
||||||
|
|
||||||
//Base 64 decode each part of the jwe
|
|
||||||
String decodedHeader = new String(Base64.decodeBase64(jwe.getHeader().toString()));
|
|
||||||
JweHeader unencryptedHeader = new JweHeader(decodedHeader);
|
|
||||||
jwe.setHeader(unencryptedHeader);
|
|
||||||
|
|
||||||
String decodedEncryptionKey = new String(Base64.decodeBase64(jwe.getEncryptedKey().toString()));
|
|
||||||
//sets decoded key on jwe so that it can be decrypted
|
|
||||||
jwe.setEncryptedKey(decodedEncryptionKey.getBytes());
|
|
||||||
|
|
||||||
String decodedCiphertext = new String(Base64.decodeBase64(jwe.getCiphertext().toString()));
|
|
||||||
//sets decoded ciphertext on jwe so that it can be decrypted
|
|
||||||
jwe.setCiphertext(decodedCiphertext.getBytes());
|
|
||||||
|
|
||||||
//decode signature, but don't set it on jwe yet. first has to be verified (see below)
|
|
||||||
String decodedSig = new String(Base64.decodeBase64(jwe.getSignature()));
|
|
||||||
|
|
||||||
|
|
||||||
PrivateKey contentEncryptionKey = null;
|
|
||||||
PublicKey contentIntegrityKey = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(jwe.getHeader().getKeyDerivationFunction());
|
|
||||||
KeyPair keyPair = keyGen.genKeyPair();
|
|
||||||
contentEncryptionKey = keyPair.getPrivate();
|
|
||||||
contentIntegrityKey = keyPair.getPublic();
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e1) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
jwe.setCiphertext(decryptCipherText(jwe, contentEncryptionKey).getBytes());
|
|
||||||
jwe.setEncryptedKey(decryptEncryptionKey(jwe));
|
|
||||||
|
|
||||||
//generate signature for decrypted signature base in order to verify that decryption worked
|
|
||||||
String signature = null;
|
|
||||||
try {
|
|
||||||
HmacSigner hmacSigner = new HmacSigner(contentIntegrityKey.getEncoded());
|
|
||||||
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 != decodedSig){
|
|
||||||
throw new IllegalArgumentException("Didn't decrypt correctly. Decoded Sig and generated Sig do not match");
|
|
||||||
}
|
|
||||||
|
|
||||||
jwe.setSignature(decodedSig);
|
|
||||||
|
|
||||||
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Cannot use Hmac for decryption");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Not a valid decrypting algorithm");
|
|
||||||
}
|
|
||||||
return jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
package org.mitre.jwt.encryption.impl;
|
|
||||||
|
|
||||||
import java.security.KeyPair;
|
|
||||||
import java.security.KeyPairGenerator;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
|
||||||
import org.mitre.jwe.model.JweHeader;
|
|
||||||
import org.mitre.jwt.encryption.AbstractJweEncrypter;
|
|
||||||
import org.mitre.jwt.model.JwtClaims;
|
|
||||||
import org.mitre.jwt.signer.impl.HmacSigner;
|
|
||||||
|
|
||||||
public class Encrypter extends AbstractJweEncrypter {
|
|
||||||
|
|
||||||
private Jwe jwe;
|
|
||||||
|
|
||||||
private JweHeader header;
|
|
||||||
|
|
||||||
private JwtClaims claims;
|
|
||||||
|
|
||||||
private String signature;
|
|
||||||
|
|
||||||
public Encrypter(Jwe jwe) {
|
|
||||||
setJwe(jwe);
|
|
||||||
setHeader(jwe.getHeader());
|
|
||||||
setClaims(jwe.getClaims());
|
|
||||||
setSignature(jwe.getSignature());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jwe getJwe() {
|
|
||||||
return jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJwe(Jwe jwe) {
|
|
||||||
this.jwe = jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public JweHeader getHeader() {
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeader(JweHeader header) {
|
|
||||||
this.header = header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JwtClaims getClaims() {
|
|
||||||
return claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClaims(JwtClaims claims) {
|
|
||||||
this.claims = claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSignature(String signature) {
|
|
||||||
this.signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException {
|
|
||||||
|
|
||||||
String alg = jwe.getHeader().getAlgorithm();
|
|
||||||
String iv = jwe.getHeader().getIntegrity();
|
|
||||||
|
|
||||||
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
|
||||||
|
|
||||||
//generate CEK and CIK
|
|
||||||
|
|
||||||
PrivateKey contentEncryptionKey = null;
|
|
||||||
PublicKey contentIntegrityKey = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(jwe.getHeader().getKeyDerivationFunction());
|
|
||||||
KeyPair keyPair = keyGen.genKeyPair();
|
|
||||||
contentEncryptionKey = keyPair.getPrivate();
|
|
||||||
contentIntegrityKey = keyPair.getPublic();
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e1) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey));
|
|
||||||
jwe.setEncryptedKey(encryptKey(jwe));
|
|
||||||
|
|
||||||
if(iv.equals("HS256") || iv.equals("HS384") || iv.equals("HS512")){
|
|
||||||
|
|
||||||
HmacSigner hmacSigner = new HmacSigner(contentIntegrityKey.getEncoded());
|
|
||||||
jwe = (Jwe) hmacSigner.sign(jwe);
|
|
||||||
|
|
||||||
} else if(iv.equals("RS256") || iv.equals("RS384") || iv.equals("RS512")) {
|
|
||||||
throw new IllegalArgumentException("Integrity Value must use Hmac signing");
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Not a valid integrity value algorithm");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
|
||||||
throw new IllegalArgumentException("Cannot use Hmac for encryption");
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Not a valid signing algorithm");
|
|
||||||
}
|
|
||||||
|
|
||||||
return jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
package org.mitre.jwt.encryption.impl;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
|
||||||
|
import org.mitre.jwe.model.Jwe;
|
||||||
|
import org.mitre.jwt.encryption.AbstractJweDecrypter;
|
||||||
|
import org.mitre.jwt.signer.impl.HmacSigner;
|
||||||
|
|
||||||
|
|
||||||
|
public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
|
|
||||||
|
public RsaDecrypter() {
|
||||||
|
//TODO: Put something here
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Jwe decrypt(String encryptedJwe) {
|
||||||
|
|
||||||
|
Jwe jwe = Jwe.parse(encryptedJwe);
|
||||||
|
|
||||||
|
String alg = jwe.getHeader().getAlgorithm();
|
||||||
|
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
||||||
|
|
||||||
|
PrivateKey contentEncryptionKey = null;
|
||||||
|
PublicKey contentIntegrityKey = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(jwe.getHeader().getKeyDerivationFunction());
|
||||||
|
KeyPair keyPair = keyGen.genKeyPair();
|
||||||
|
contentEncryptionKey = keyPair.getPrivate();
|
||||||
|
contentIntegrityKey = keyPair.getPublic();
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
jwe.setCiphertext(decryptCipherText(jwe, contentEncryptionKey).getBytes());
|
||||||
|
jwe.setEncryptedKey(decryptEncryptionKey(jwe));
|
||||||
|
|
||||||
|
//generate signature for decrypted signature base in order to verify that decryption worked
|
||||||
|
String signature = null;
|
||||||
|
try {
|
||||||
|
HmacSigner hmacSigner = new HmacSigner(contentIntegrityKey.getEncoded());
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Cannot use Hmac for decryption");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Not a valid decrypting algorithm");
|
||||||
|
}
|
||||||
|
return jwe;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String decryptCipherText(Jwe jwe, Key cek) {
|
||||||
|
Cipher cipher;
|
||||||
|
String clearTextString = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, cek);
|
||||||
|
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
|
||||||
|
clearTextString = new String(clearText);
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return clearTextString;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] decryptEncryptionKey(Jwe jwe) {
|
||||||
|
Cipher cipher;
|
||||||
|
byte[] contentMasterKey = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateKey);//TODO: Get private key from key store. Placeholder
|
||||||
|
contentMasterKey = cipher.doFinal(jwe.getEncryptedKey());
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentMasterKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package org.mitre.jwt.encryption.impl;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
import org.mitre.jwe.model.Jwe;
|
||||||
|
import org.mitre.jwt.encryption.AbstractJweEncrypter;
|
||||||
|
import org.mitre.jwt.encryption.AlgorithmLength;
|
||||||
|
import org.mitre.jwt.encryption.JwtAlgorithm;
|
||||||
|
import org.mitre.jwt.signer.impl.HmacSigner;
|
||||||
|
|
||||||
|
public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
|
|
||||||
|
|
||||||
|
public RsaEncrypter() {
|
||||||
|
//TODO: Put something here
|
||||||
|
}
|
||||||
|
|
||||||
|
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException {
|
||||||
|
|
||||||
|
String alg = jwe.getHeader().getAlgorithm();
|
||||||
|
String iv = jwe.getHeader().getIntegrity();
|
||||||
|
|
||||||
|
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
||||||
|
|
||||||
|
//generate random content master key
|
||||||
|
Key contentMasterKey = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(jwe.getHeader().getAlgorithm());
|
||||||
|
SecureRandom random = SecureRandom.getInstance(jwe.getHeader().getAlgorithm());
|
||||||
|
keyGen.initialize(1024, random);
|
||||||
|
KeyPair pair = keyGen.generateKeyPair();
|
||||||
|
contentMasterKey = pair.getPublic();
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//generate CEK and CIK
|
||||||
|
|
||||||
|
String algorithmLength = AlgorithmLength.getByName(jwe.getHeader().getEncryptionMethod()).getStandardName();
|
||||||
|
int keyLength = Integer.parseInt(algorithmLength);
|
||||||
|
byte[] contentEncryptionKey = generateContentKey(contentMasterKey.getEncoded(), keyLength, new String("Encryption").getBytes());
|
||||||
|
byte[] contentIntegrityKey = generateContentKey(contentMasterKey.getEncoded(), keyLength, new String("Integrity").getBytes());
|
||||||
|
|
||||||
|
//encrypt claims and cmk to get ciphertext and encrypted key
|
||||||
|
jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey));
|
||||||
|
jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey));
|
||||||
|
|
||||||
|
//Signer must be hmac
|
||||||
|
if(iv.equals("HS256") || iv.equals("HS384") || iv.equals("HS512")){
|
||||||
|
|
||||||
|
HmacSigner hmacSigner = new HmacSigner(contentIntegrityKey);
|
||||||
|
jwe = (Jwe) hmacSigner.sign(jwe);
|
||||||
|
|
||||||
|
} else if(iv.equals("RS256") || iv.equals("RS384") || iv.equals("RS512")) {
|
||||||
|
throw new IllegalArgumentException("Integrity Value must use Hmac signing");
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Not a valid integrity value algorithm");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
||||||
|
throw new IllegalArgumentException("Cannot use Hmac for encryption");
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Not a valid signing algorithm");
|
||||||
|
}
|
||||||
|
|
||||||
|
return jwe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] encryptKey(Jwe jwe, Key cmk) {
|
||||||
|
|
||||||
|
//TODO:Get public key from keystore, currently null
|
||||||
|
Cipher cipher;
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance(JwtAlgorithm.getByName(jwe.getHeader().getAlgorithm()).getStandardName());
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
encryptedKey = cipher.doFinal(cmk.getEncoded());
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptedKey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] encryptClaims(Jwe jwe, byte[] contentEncryptionKey) {
|
||||||
|
|
||||||
|
Cipher cipher;
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance(JwtAlgorithm.getByName(jwe.getHeader().getAlgorithm()).getStandardName());
|
||||||
|
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(contentEncryptionKey, 0, contentEncryptionKey.length, "RSA"));
|
||||||
|
cipherText = cipher.doFinal(jwe.getClaims().toString().getBytes());
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cipherText;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -124,17 +124,7 @@ public class HmacSigner extends AbstractJwtSigner implements InitializingBean {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet(){
|
public void afterPropertiesSet(){
|
||||||
|
initializeMac();
|
||||||
try {
|
|
||||||
mac = Mac.getInstance(JwsAlgorithm.getByName(super.getAlgorithm())
|
|
||||||
.getStandardName());
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug(JwsAlgorithm.getByName(getAlgorithm()).getStandardName()
|
|
||||||
+ " ECDSA Signer ready for business");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -147,14 +137,7 @@ public class HmacSigner extends AbstractJwtSigner implements InitializingBean {
|
||||||
@Override
|
@Override
|
||||||
public String generateSignature(String signatureBase) throws NoSuchAlgorithmException {
|
public String generateSignature(String signatureBase) throws NoSuchAlgorithmException {
|
||||||
|
|
||||||
List<String> parts = Lists.newArrayList(Splitter.on(".").split(signatureBase));
|
afterPropertiesSet();
|
||||||
|
|
||||||
if (parts.size() == 2) {
|
|
||||||
initializeMac();
|
|
||||||
}
|
|
||||||
else if (parts.size() == 3) {
|
|
||||||
initializeMacJwe(signatureBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (passphrase == null) {
|
if (passphrase == null) {
|
||||||
throw new IllegalArgumentException("Passphrase cannot be null");
|
throw new IllegalArgumentException("Passphrase cannot be null");
|
||||||
|
@ -194,6 +177,7 @@ public class HmacSigner extends AbstractJwtSigner implements InitializingBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializeMac() {
|
public void initializeMac() {
|
||||||
|
// TODO: check if it's already been done
|
||||||
try {
|
try {
|
||||||
mac = Mac.getInstance(JwsAlgorithm.getByName(super.getAlgorithm()).getStandardName());
|
mac = Mac.getInstance(JwsAlgorithm.getByName(super.getAlgorithm()).getStandardName());
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
@ -201,7 +185,7 @@ public class HmacSigner extends AbstractJwtSigner implements InitializingBean {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: nuke and clean up
|
||||||
public void initializeMacJwe(String signatureBase) {
|
public void initializeMacJwe(String signatureBase) {
|
||||||
List<String> parts = Lists.newArrayList(Splitter.on(".").split(signatureBase));
|
List<String> parts = Lists.newArrayList(Splitter.on(".").split(signatureBase));
|
||||||
String header = parts.get(0);
|
String header = parts.get(0);
|
||||||
|
|
|
@ -36,8 +36,6 @@ import org.springframework.util.Assert;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JWT Signer using either the RSA SHA-256, SHA-384, SHA-512 hash algorithm
|
* JWT Signer using either the RSA SHA-256, SHA-384, SHA-512 hash algorithm
|
||||||
|
@ -138,14 +136,7 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws NoSuchAlgorithmException, GeneralSecurityException {
|
public void afterPropertiesSet() throws NoSuchAlgorithmException, GeneralSecurityException {
|
||||||
|
initializeSigner();
|
||||||
// unsupported algorithm will throw a NoSuchAlgorithmException
|
|
||||||
signer = Signature.getInstance(JwsAlgorithm.getByName(super.getAlgorithm()).getStandardName()); // ,PROVIDER);
|
|
||||||
|
|
||||||
loadKeysFromKeystore();
|
|
||||||
|
|
||||||
logger.debug(JwsAlgorithm.getByName(getAlgorithm()).getStandardName() + " RSA Signer ready for business");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,13 +167,13 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean {
|
||||||
public String generateSignature(String signatureBase) throws NoSuchAlgorithmException {
|
public String generateSignature(String signatureBase) throws NoSuchAlgorithmException {
|
||||||
|
|
||||||
String sig = null;
|
String sig = null;
|
||||||
List<String> parts = Lists.newArrayList(Splitter.on(".").split(signatureBase));
|
try {
|
||||||
|
afterPropertiesSet();
|
||||||
if(parts.size() == 2) {
|
} catch (GeneralSecurityException e1) {
|
||||||
initializeSigner();
|
// TODO Auto-generated catch block
|
||||||
} else if (parts.size() == 3) {
|
e1.printStackTrace();
|
||||||
initializeSignerJwe(signatureBase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
signer.initSign(privateKey);
|
signer.initSign(privateKey);
|
||||||
signer.update(signatureBase.getBytes("UTF-8"));
|
signer.update(signatureBase.getBytes("UTF-8"));
|
||||||
|
@ -238,16 +229,6 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean {
|
||||||
public void initializeSigner() throws NoSuchAlgorithmException{
|
public void initializeSigner() throws NoSuchAlgorithmException{
|
||||||
signer = Signature.getInstance(JwsAlgorithm.getByName(super.getAlgorithm()).getStandardName());
|
signer = Signature.getInstance(JwsAlgorithm.getByName(super.getAlgorithm()).getStandardName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializeSignerJwe(String signatureBase) throws NoSuchAlgorithmException {
|
|
||||||
|
|
||||||
List<String> parts = Lists.newArrayList(Splitter.on(".").split(signatureBase));
|
|
||||||
String header = parts.get(0);
|
|
||||||
JsonParser parser = new JsonParser();
|
|
||||||
JsonObject object = (JsonObject) parser.parse(header);
|
|
||||||
|
|
||||||
signer = Signature.getInstance(JwsAlgorithm.getByName(object.get("int").getAsString()).getStandardName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
|
|
Loading…
Reference in New Issue