updated encrypter/decrypter to store keys as member variables rather than to pass them in
parent
61c7231d9a
commit
95dcb10472
|
@ -2,7 +2,6 @@ package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
import javax.crypto.BadPaddingException;
|
||||||
|
@ -13,11 +12,11 @@ import org.mitre.jwe.model.Jwe;
|
||||||
|
|
||||||
public interface JweDecrypter {
|
public interface JweDecrypter {
|
||||||
|
|
||||||
public Jwe decrypt(String encryptedJwe, Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
public Jwe decrypt(String encryptedJwe) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||||
|
|
||||||
public byte[] decryptCipherText(Jwe jwe, byte[] cek) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
public byte[] decryptCipherText(Jwe jwe, byte[] cek) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||||
|
|
||||||
public byte[] decryptEncryptionKey(Jwe jwe, Key privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
public byte[] decryptEncryptionKey(Jwe jwe) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.mitre.jwt.encryption;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
|
||||||
|
@ -19,11 +18,11 @@ import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
public interface JweEncrypter {
|
public interface JweEncrypter {
|
||||||
|
|
||||||
public byte[] encryptKey(Jwe jwe, byte[] cmk, Key publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException;
|
public byte[] encryptKey(Jwe jwe, byte[] cmk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException;
|
||||||
|
|
||||||
public byte[] encryptClaims(Jwe jwe, byte[] cik) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException;
|
public byte[] encryptClaims(Jwe jwe, byte[] cik) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException;
|
||||||
|
|
||||||
public Jwe encryptAndSign(Jwe jwe, Key publicKey) throws NoSuchAlgorithmException, JsonIOException, JsonSyntaxException, IOException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException;
|
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException, JsonIOException, JsonSyntaxException, IOException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException;
|
||||||
|
|
||||||
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException;
|
public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@ package org.mitre.jwt.encryption.impl;
|
||||||
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
import javax.crypto.BadPaddingException;
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
|
@ -20,8 +21,11 @@ import org.mitre.jwt.encryption.JweAlgorithms;
|
||||||
|
|
||||||
public class RsaDecrypter extends AbstractJweDecrypter {
|
public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
|
|
||||||
|
private PublicKey publicKey;
|
||||||
|
private PrivateKey privateKey;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Jwe decrypt(String encryptedJwe, Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
public Jwe decrypt(String encryptedJwe) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
||||||
|
|
||||||
Jwe jwe = Jwe.parse(encryptedJwe);
|
Jwe jwe = Jwe.parse(encryptedJwe);
|
||||||
|
|
||||||
|
@ -29,7 +33,7 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
if(alg.equals("RSA1_5") || alg.equals("RSA-OAEP") || alg.equals("ECDH-ES") || alg.equals("A128KW") || alg.equals("A256KW")) {
|
if(alg.equals("RSA1_5") || alg.equals("RSA-OAEP") || alg.equals("ECDH-ES") || alg.equals("A128KW") || alg.equals("A256KW")) {
|
||||||
|
|
||||||
//decrypt to get cmk to be used for cek and cik
|
//decrypt to get cmk to be used for cek and cik
|
||||||
jwe.setEncryptedKey(decryptEncryptionKey(jwe, privateKey));
|
jwe.setEncryptedKey(decryptEncryptionKey(jwe));
|
||||||
|
|
||||||
//generation of cek and cik
|
//generation of cek and cik
|
||||||
byte[] contentEncryptionKey = null;
|
byte[] contentEncryptionKey = null;
|
||||||
|
@ -75,11 +79,11 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] decryptEncryptionKey(Jwe jwe, Key privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
public byte[] decryptEncryptionKey(Jwe jwe) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
|
||||||
if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
|
if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
Cipher cipher = Cipher.getInstance("RSA");
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
|
||||||
byte[] contentMasterKey = cipher.doFinal(jwe.getEncryptedKey());
|
byte[] contentMasterKey = cipher.doFinal(jwe.getEncryptedKey());
|
||||||
|
|
||||||
return contentMasterKey;
|
return contentMasterKey;
|
||||||
|
@ -89,4 +93,20 @@ public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PublicKey getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicKey(PublicKey publicKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrivateKey getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(PrivateKey privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@ package org.mitre.jwt.encryption.impl;
|
||||||
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
@ -22,7 +23,10 @@ import org.mitre.jwt.signer.impl.HmacSigner;
|
||||||
|
|
||||||
public class RsaEncrypter extends AbstractJweEncrypter {
|
public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
|
|
||||||
public Jwe encryptAndSign(Jwe jwe, Key publicKey) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
|
private PublicKey publicKey;
|
||||||
|
private PrivateKey privateKey;
|
||||||
|
|
||||||
|
public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
|
||||||
|
|
||||||
String alg = jwe.getHeader().getAlgorithm();
|
String alg = jwe.getHeader().getAlgorithm();
|
||||||
String integrityAlg = jwe.getHeader().getIntegrity();
|
String integrityAlg = jwe.getHeader().getIntegrity();
|
||||||
|
@ -48,7 +52,7 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
|
|
||||||
//encrypt claims and cmk to get ciphertext and encrypted key
|
//encrypt claims and cmk to get ciphertext and encrypted key
|
||||||
jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey));
|
jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey));
|
||||||
jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey, publicKey));
|
jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey));
|
||||||
|
|
||||||
//Signer must be hmac
|
//Signer must be hmac
|
||||||
if(integrityAlg.equals("HS256") || integrityAlg.equals("HS384") || integrityAlg.equals("HS512")){
|
if(integrityAlg.equals("HS256") || integrityAlg.equals("HS384") || integrityAlg.equals("HS512")){
|
||||||
|
@ -67,12 +71,12 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
return jwe;
|
return jwe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encryptKey(Jwe jwe, byte[] contentMasterKey, Key publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
public byte[] encryptKey(Jwe jwe, byte[] contentMasterKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
|
||||||
if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
|
if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
Cipher cipher = Cipher.getInstance("RSA");
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
cipher.init(Cipher.ENCRYPT_MODE, getPublicKey());
|
||||||
byte[] encryptedKey = cipher.doFinal(contentMasterKey);
|
byte[] encryptedKey = cipher.doFinal(contentMasterKey);
|
||||||
return encryptedKey;
|
return encryptedKey;
|
||||||
|
|
||||||
|
@ -109,4 +113,20 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PublicKey getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicKey(PublicKey publicKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrivateKey getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(PrivateKey privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ import com.google.gson.JsonPrimitive;
|
||||||
*/
|
*/
|
||||||
public class ClaimSet {
|
public class ClaimSet {
|
||||||
|
|
||||||
|
private String jsonString;
|
||||||
|
|
||||||
// the LinkedHashMap preserves insertion order
|
// the LinkedHashMap preserves insertion order
|
||||||
private Map<String, Object> claims = new LinkedHashMap<String, Object>();
|
private Map<String, Object> claims = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
|
@ -94,6 +96,7 @@ public class ClaimSet {
|
||||||
* Set an extension claim
|
* Set an extension claim
|
||||||
*/
|
*/
|
||||||
public void setClaim(String key, Object value) {
|
public void setClaim(String key, Object value) {
|
||||||
|
jsonString = null;
|
||||||
claims.put(key, value);
|
claims.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +104,7 @@ public class ClaimSet {
|
||||||
* Set a primitive claim
|
* Set a primitive claim
|
||||||
*/
|
*/
|
||||||
public void setClaim(String key, JsonPrimitive prim) {
|
public void setClaim(String key, JsonPrimitive prim) {
|
||||||
|
jsonString = null;
|
||||||
if (prim == null) {
|
if (prim == null) {
|
||||||
// in case we get here with a primitive null
|
// in case we get here with a primitive null
|
||||||
claims.put(key, prim);
|
claims.put(key, prim);
|
||||||
|
@ -111,6 +115,7 @@ public class ClaimSet {
|
||||||
} else if (prim.isString()) {
|
} else if (prim.isString()) {
|
||||||
claims.put(key, prim.getAsString());
|
claims.put(key, prim.getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,4 +208,11 @@ public class ClaimSet {
|
||||||
loadFromJsonObject(json);
|
loadFromJsonObject(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if(jsonString == null) {
|
||||||
|
jsonString = this.getAsJsonObject().toString();
|
||||||
|
}
|
||||||
|
return jsonString;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import org.apache.commons.codec.binary.Base64;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
public class Jwt {
|
public class Jwt {
|
||||||
|
|
||||||
|
@ -124,11 +123,9 @@ public class Jwt {
|
||||||
* The signature base of a JWT is the header in Base64, a period ".", and the claims in Base64.
|
* The signature base of a JWT is the header in Base64, a period ".", and the claims in Base64.
|
||||||
*/
|
*/
|
||||||
public String getSignatureBase() {
|
public String getSignatureBase() {
|
||||||
JsonObject h = header.getAsJsonObject();
|
|
||||||
JsonObject c = claims.getAsJsonObject();
|
|
||||||
|
|
||||||
String h64 = new String(Base64.encodeBase64URLSafe(h.toString().getBytes()));
|
String h64 = new String(Base64.encodeBase64URLSafe(header.toString().getBytes()));
|
||||||
String c64 = new String(Base64.encodeBase64URLSafe(c.toString().getBytes()));
|
String c64 = new String(Base64.encodeBase64URLSafe(claims.toString().getBytes()));
|
||||||
|
|
||||||
return h64 + "." + c64;
|
return h64 + "." + c64;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,12 +73,16 @@ public class RsaEncrypterDecrypterTest {
|
||||||
Jwe jwe = new Jwe(new JweHeader(jweHeaderObject), null, jwePlaintextString.getBytes(), null);
|
Jwe jwe = new Jwe(new JweHeader(jweHeaderObject), null, jwePlaintextString.getBytes(), null);
|
||||||
//encrypt
|
//encrypt
|
||||||
RsaEncrypter rsaEncrypter = new RsaEncrypter();
|
RsaEncrypter rsaEncrypter = new RsaEncrypter();
|
||||||
jwe = rsaEncrypter.encryptAndSign(jwe, publicKey);
|
rsaEncrypter.setPublicKey(publicKey);
|
||||||
|
rsaEncrypter.setPrivateKey(privateKey);
|
||||||
|
jwe = rsaEncrypter.encryptAndSign(jwe);
|
||||||
|
|
||||||
//decrypt
|
//decrypt
|
||||||
RsaDecrypter rsaDecrypter = new RsaDecrypter();
|
RsaDecrypter rsaDecrypter = new RsaDecrypter();
|
||||||
|
rsaDecrypter.setPublicKey(publicKey);
|
||||||
|
rsaDecrypter.setPrivateKey(privateKey);
|
||||||
String encryptedJweString = jwe.toString();
|
String encryptedJweString = jwe.toString();
|
||||||
jwe = rsaDecrypter.decrypt(encryptedJweString, privateKey);
|
jwe = rsaDecrypter.decrypt(encryptedJweString);
|
||||||
|
|
||||||
String jweDecryptedCleartext = new String(jwe.getCiphertext());
|
String jweDecryptedCleartext = new String(jwe.getCiphertext());
|
||||||
//test ALL THE THINGS
|
//test ALL THE THINGS
|
||||||
|
|
Loading…
Reference in New Issue