From 025f7f3d66301b91cce9fc87f9ff9571f123f8cb Mon Sep 17 00:00:00 2001 From: Mike Derryberry Date: Fri, 6 Jul 2012 09:12:43 -0400 Subject: [PATCH] updated encryption to sign using int value rather than alg --- .../java/org/mitre/jwe/model/JweHeader.java | 40 ++++++++++++++++++ .../{RsaDecrypter.java => Decrypter.java} | 14 ++++++- .../{RsaEncrypter.java => Encrypter.java} | 28 +++++++++---- .../org/mitre/jwt/signer/impl/HmacSigner.java | 41 ++++++++++++++++++- .../org/mitre/jwt/signer/impl/RsaSigner.java | 22 +++++++--- 5 files changed, 128 insertions(+), 17 deletions(-) rename openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/{RsaDecrypter.java => Decrypter.java} (69%) rename openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/{RsaEncrypter.java => Encrypter.java} (65%) diff --git a/openid-connect-common/src/main/java/org/mitre/jwe/model/JweHeader.java b/openid-connect-common/src/main/java/org/mitre/jwe/model/JweHeader.java index e750f74fb..78ed1e097 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwe/model/JweHeader.java +++ b/openid-connect-common/src/main/java/org/mitre/jwe/model/JweHeader.java @@ -70,6 +70,46 @@ public class JweHeader extends JwtHeader{ super.loadFromJsonObject(pass); } + public String getIntegrity() { + return INTEGRITY; + } + + public String getInitializationVector() { + return INITIALIZATION_VECTOR; + } + + public String getEphemeralPublicKey() { + return EPHEMERAL_PUBLIC_KEY; + } + + public String getCompressionAlgorithm() { + return COMPRESSION_ALGORITHM; + } + + public String getJsonSetUrl() { + return JSON_SET_URL; + } + + public String getJsonWebKey() { + return JSON_WEB_KEY; + } + + public String getX509Url() { + return X509_URL; + } + + public String getX509CertificateThumbprint() { + return X509_CERTIFICATE_THUMBPRINT; + } + + public String getX509CertificateChain() { + return X509_CERTIFICATE_CHAIN; + } + + public String getKeyId() { + return KEY_ID; + } + public void setIv(String iv) { setClaim(INITIALIZATION_VECTOR, iv); } 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/Decrypter.java similarity index 69% rename from openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java rename to openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/Decrypter.java index a0d5f2425..b79e919f1 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/Decrypter.java @@ -5,11 +5,11 @@ import org.mitre.jwe.model.Jwe; import org.mitre.jwt.encryption.AbstractJweDecrypter; import org.mitre.jwt.model.JwtHeader; -public class RsaDecrypter extends AbstractJweDecrypter { +public class Decrypter extends AbstractJweDecrypter { private Jwe jwe; - public RsaDecrypter(Jwe jwe) { + public Decrypter(Jwe jwe) { setJwe(jwe); } @@ -29,10 +29,20 @@ public class RsaDecrypter extends AbstractJweDecrypter { 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())); JwtHeader unencryptedHeader = new JwtHeader(decodedHeader); + + String decodedEncryptionKey = new String(Base64.decodeBase64(jwe.getEncryptedKey().toString())); + jwe.setEncryptedKey(decodedEncryptionKey.getBytes()); + + String decodedCiphertext = new String(Base64.decodeBase64(jwe.getCiphertext().toString())); + jwe.setCiphertext(decodedCiphertext.getBytes()); + String decodedSig = new String(Base64.decodeBase64(jwe.getSignature())); + //create new jwe using the decoded header and signature, and decrypt the ciphertext and key + jwe.setHeader(unencryptedHeader); jwe.setCiphertext(decryptCipherText(jwe).getBytes()); jwe.setEncryptedKey(decryptEncryptionKey(jwe)); 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/Encrypter.java similarity index 65% rename from openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java rename to openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/Encrypter.java index 85fcd3335..e81e3581d 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/Encrypter.java @@ -6,9 +6,9 @@ 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.RsaSigner; +import org.mitre.jwt.signer.impl.HmacSigner; -public class RsaEncrypter extends AbstractJweEncrypter { +public class Encrypter extends AbstractJweEncrypter { private Jwe jwe; @@ -18,7 +18,7 @@ public class RsaEncrypter extends AbstractJweEncrypter { private String signature; - public RsaEncrypter(Jwe jwe) { + public Encrypter(Jwe jwe) { setJwe(jwe); setHeader(jwe.getHeader()); setClaims(jwe.getClaims()); @@ -62,18 +62,28 @@ public class RsaEncrypter extends AbstractJweEncrypter { public Jwe encryptAndSign(Jwe jwe) { String alg = jwe.getHeader().getAlgorithm(); + String iv = jwe.getHeader().getIntegrity(); + if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) { jwe.setCiphertext(encryptClaims(jwe)); jwe.setEncryptedKey(encryptKey(jwe)); - RsaSigner rsaSigner = new RsaSigner(); //TODO: Add parameters to RsaSigner. ie: keys from keystore (null at the moment) - try { - jwe = (Jwe) rsaSigner.sign(jwe); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + if(iv.equals("HS256") || iv.equals("HS384") || iv.equals("HS512")){ + + HmacSigner hmacSigner = new HmacSigner(); //TODO: Add parameters to RsaSigner. ie: keys from keystore (null at the moment) + try { + jwe = (Jwe) hmacSigner.sign(jwe); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } 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"); diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/HmacSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/HmacSigner.java index b73113120..dd48d9bd0 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/HmacSigner.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/HmacSigner.java @@ -19,6 +19,7 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; +import java.util.List; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; @@ -31,6 +32,11 @@ import org.mitre.jwt.signer.JwsAlgorithm; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + /** * JWT Signer using either the HMAC SHA-256, SHA-384, SHA-512 hash algorithm * @@ -140,7 +146,16 @@ public class HmacSigner extends AbstractJwtSigner implements InitializingBean { */ @Override public String generateSignature(String signatureBase) throws NoSuchAlgorithmException { - afterPropertiesSet(); + + List parts = Lists.newArrayList(Splitter.on(".").split(signatureBase)); + + if (parts.size() == 2) { + initializeMac(); + } + else if (parts.size() == 3) { + initializeMacJwe(signatureBase); + } + if (passphrase == null) { throw new IllegalArgumentException("Passphrase cannot be null"); } @@ -177,6 +192,30 @@ public class HmacSigner extends AbstractJwtSigner implements InitializingBean { public void setPassphrase(String passphrase) { this.passphrase = passphrase; } + + public void initializeMac() { + try { + mac = Mac.getInstance(JwsAlgorithm.getByName(super.getAlgorithm()).getStandardName()); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void initializeMacJwe(String signatureBase) { + List parts = Lists.newArrayList(Splitter.on(".").split(signatureBase)); + String header = parts.get(0); + JsonParser parser = new JsonParser(); + JsonObject object = (JsonObject) parser.parse(header); + + try { + mac = Mac.getInstance(JwsAlgorithm.getByName(object.get("int").getAsString()) + .getStandardName()); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } /* diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java index 4ab53303d..858453c88 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java @@ -36,6 +36,8 @@ import org.springframework.util.Assert; import com.google.common.base.Splitter; 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 @@ -174,13 +176,13 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { public String generateSignature(String signatureBase) throws NoSuchAlgorithmException { String sig = null; - try { + List parts = Lists.newArrayList(Splitter.on(".").split(signatureBase)); + + if(parts.size() == 2) { initializeSigner(); - } catch (GeneralSecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + } else if (parts.size() == 3) { + initializeSignerJwe(signatureBase); } - try { signer.initSign(privateKey); signer.update(signatureBase.getBytes("UTF-8")); @@ -236,6 +238,16 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { public void initializeSigner() throws NoSuchAlgorithmException{ signer = Signature.getInstance(JwsAlgorithm.getByName(super.getAlgorithm()).getStandardName()); } + + public void initializeSignerJwe(String signatureBase) throws NoSuchAlgorithmException { + + List 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)