From caf2a7b494b32b6a8af65b021d731ab5c005d1e0 Mon Sep 17 00:00:00 2001 From: Mike Derryberry Date: Wed, 27 Jun 2012 15:44:26 -0400 Subject: [PATCH] updated encryption service to encrypt key and claims and then sign the jwe. decryption updated to decrypt encrypted key and ciphertext --- .../AbstractOIDCAuthenticationFilter.java | 3 - .../java/org/mitre/jwe/model/ClaimSet.java | 207 ------------------ .../main/java/org/mitre/jwe/model/Jwe.java | 62 ++++-- .../src/main/java/org/mitre/jwk/model/EC.java | 4 - .../jwt/encryption/AbstractJweEncrypter.java | 41 ++++ .../mitre/jwt/encryption/JwtEncrypter.java | 119 +--------- .../jwt/encryption/impl/HmacJwtDecrypter.java | 5 - .../jwt/encryption/impl/HmacJwtEncrypter.java | 87 -------- .../jwt/encryption/impl/RsaDecrypter.java | 121 ++++++++++ .../jwt/encryption/impl/RsaEncrypter.java | 161 ++++++++++++++ .../impl/RsaJwtClaimsDecrypter.java | 69 ------ .../impl/RsaJwtClaimsEncrypter.java | 69 ------ .../jwt/encryption/impl/RsaJwtEncrypter.java | 81 ------- .../org/mitre/jwt/model/EncryptedJwt.java | 96 -------- .../JwtSigningAndValidationService.java | 1 - ...JwtSigningAndValidationServiceDefault.java | 3 - 16 files changed, 371 insertions(+), 758 deletions(-) delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwe/model/ClaimSet.java create mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtDecrypter.java delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtEncrypter.java create mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java create mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsDecrypter.java delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsEncrypter.java delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtEncrypter.java delete mode 100644 openid-connect-common/src/main/java/org/mitre/jwt/model/EncryptedJwt.java diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilter.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilter.java index 8901a363c..ec14334cf 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilter.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/AbstractOIDCAuthenticationFilter.java @@ -22,14 +22,11 @@ import java.net.URLEncoder; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; -import java.security.cert.CertificateException; import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/openid-connect-common/src/main/java/org/mitre/jwe/model/ClaimSet.java b/openid-connect-common/src/main/java/org/mitre/jwe/model/ClaimSet.java deleted file mode 100644 index ee82ec6ca..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwe/model/ClaimSet.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.mitre.jwe.model; -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.codec.binary.Base64; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; - -/** - * Generic container for JSON-based claims. Backed with a {@link Map} that preserves - * insertion order. Several convenience methods for getting and setting claims in different - * formats. - * @author jricher - * - */ -public class ClaimSet { - - // the LinkedHashMap preserves insertion order - private Map claims = new LinkedHashMap(); - - public ClaimSet() { - - } - - public ClaimSet(JsonObject json) { - loadFromJsonObject(json); - } - - public ClaimSet(String b64) { - loadFromBase64JsonObjectString(b64); - } - - /** - * Get an extension claim - */ - public Object getClaim(String key) { - return claims.get(key); - } - - /** - * Get a claim as a string - */ - public String getClaimAsString(String key) { - Object v = claims.get(key); - if (v != null) { - return v.toString(); - } else { - return null; - } - } - - /** - * Get a claim as a Date - */ - public Date getClaimAsDate(String key) { - Object v = claims.get(key); - if (v != null) { - if (v instanceof Date) { - return (Date) v; - } else if (v instanceof Long) { - return new Date((Long) v); - } else { - return null; - } - } else { - return null; - } - } - - /** - * Set an extension claim - */ - public void setClaim(String key, Object value) { - claims.put(key, value); - } - - /** - * Set a primitive claim - */ - public void setClaim(String key, JsonPrimitive prim) { - if (prim == null) { - // in case we get here with a primitive null - claims.put(key, prim); - } else if (prim.isBoolean()) { - claims.put(key, prim.getAsBoolean()); - } else if (prim.isNumber()) { - claims.put(key, prim.getAsNumber()); - } else if (prim.isString()) { - claims.put(key, prim.getAsString()); - } - } - - /** - * Remove an extension claim - */ - public Object removeClaim(String key) { - return claims.remove(key); - } - - - /** - * Clear all claims from this ClaimSet - * @see java.util.Map#clear() - */ - public void clear() { - claims.clear(); - } - - /** - * Get a copy of this claim set as a JsonObject. The JsonObject is not - * backed by a live copy of this ClaimSet. - * @return a copy of the data in this header in a JsonObject - */ - public JsonObject getAsJsonObject() { - JsonObject o = new JsonObject(); - - - /* - * We step through the claims object and serialize the internal values as - * appropriate to JsonElements. - */ - - if (this.claims != null) { - for (Map.Entry claim : this.claims.entrySet()) { - if (claim.getValue() instanceof JsonElement) { - // raw JSON elements get passed through directly - o.add(claim.getKey(), (JsonElement)claim.getValue()); - } else if (claim.getValue() instanceof String) { - o.addProperty(claim.getKey(), (String)claim.getValue()); - } else if (claim.getValue() instanceof Number) { - o.addProperty(claim.getKey(), (Number)claim.getValue()); - } else if (claim.getValue() instanceof Boolean) { - o.addProperty(claim.getKey(), (Boolean)claim.getValue()); - } else if (claim.getValue() instanceof Character) { - o.addProperty(claim.getKey(), (Character)claim.getValue()); - } else if (claim.getValue() instanceof Date) { - // dates get serialized out as integers - o.addProperty(claim.getKey(), ((Date)claim.getValue()).getTime() / 1000L); - } else if (claim.getValue() != null) { - // try to put it in as a string - o.addProperty(claim.getKey(), claim.getValue().toString()); - } else { - // otherwise add in as a null - o.add(claim.getKey(), null); - } - } - } - - return o; - } - - /** - * Load new claims from the given json object. Will replace any existing claims, but does not clear claim set. - * @param json - */ - public void loadFromJsonObject(JsonObject json) { - for (Entry element : json.entrySet()) { - if (element.getValue().isJsonNull()) { - // nulls get stored as java nulls - setClaim(element.getKey(), null); - } else if (element.getValue().isJsonPrimitive()){ - // we handle all primitives in here - JsonPrimitive prim = element.getValue().getAsJsonPrimitive(); - setClaim(element.getKey(), prim); - } else { - setClaim(element.getKey(), element.getValue()); - } - } - } - - /** - * Load a new claims set from a Base64 encoded JSON Object string - */ - public void loadFromBase64JsonObjectString(String b64) { - byte[] b64decoded = Base64.decodeBase64(b64); - - JsonParser parser = new JsonParser(); - JsonObject json = parser.parse(new InputStreamReader(new ByteArrayInputStream(b64decoded))).getAsJsonObject(); - - loadFromJsonObject(json); - } - -} - diff --git a/openid-connect-common/src/main/java/org/mitre/jwe/model/Jwe.java b/openid-connect-common/src/main/java/org/mitre/jwe/model/Jwe.java index fc8be793c..c95d53fa5 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwe/model/Jwe.java +++ b/openid-connect-common/src/main/java/org/mitre/jwe/model/Jwe.java @@ -2,31 +2,36 @@ package org.mitre.jwe.model; import java.util.List; -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; +import org.apache.commons.codec.binary.Base64; +import org.mitre.jwt.model.Jwt; -public class Jwe { +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import com.google.gson.JsonObject; + +public class Jwe extends Jwt { private JweHeader header; - private String encryptedKey; + private byte[] encryptedKey; - private String ciphertext; + private byte[] ciphertext; - private String integrityValue; + private String signature; public Jwe() { this.header = new JweHeader(); this.encryptedKey = null; this.ciphertext = null; - this.integrityValue = null; + this.signature = null; } - public Jwe(JweHeader header, String encryptedKey, String ciphertext, String integrityValue) { + public Jwe(JweHeader header, byte[] encryptedKey, byte[] ciphertext, String integrityValue) { this.header = header; this.encryptedKey = encryptedKey; this.ciphertext = ciphertext; - this.integrityValue = integrityValue; + this.signature = integrityValue; } public JweHeader getHeader() { @@ -37,30 +42,49 @@ public class Jwe { this.header = header; } - public String getEncryptedKey() { + public byte[] getEncryptedKey() { return encryptedKey; } - public void setEncryptedKey(String encryptedKey) { + public void setEncryptedKey(byte[] encryptedKey) { this.encryptedKey = encryptedKey; } - public String getCiphertext() { + public byte[] getCiphertext() { return ciphertext; } - public void setCiphertext(String ciphertext) { + public void setCiphertext(byte[] ciphertext) { this.ciphertext = ciphertext; } - public String getIntegrityValue() { - return integrityValue; + public String getSignature() { + return signature; } - public void setIntegrityValue(String integrityValue) { - this.integrityValue = integrityValue; + public void setSignature(String signature) { + this.signature = signature; } + @Override + public String toString() { + return getSignatureBase() + "." + Strings.nullToEmpty(this.signature); + } + + @Override + public String getSignatureBase() { + JsonObject h = header.getAsJsonObject(); + byte[] c = ciphertext; + byte[] e = encryptedKey; + + String h64 = new String(Base64.encodeBase64URLSafe(h.toString().getBytes())); + String c64 = new String(Base64.encodeBase64URLSafe(c)); + String e64 = new String(Base64.encodeBase64URLSafe(e)); + + return h64 + "." + e64 + "." + c64; + } + + public static Jwe parse(String s) { // null string is a null token @@ -71,7 +95,7 @@ public class Jwe { // split on the dots List parts = Lists.newArrayList(Splitter.on(".").split(s)); - if (parts.size() != 3) { + if (parts.size() != 4) { throw new IllegalArgumentException("Invalid JWE format."); } @@ -80,7 +104,7 @@ public class Jwe { String c64 = parts.get(2); String i64 = parts.get(3); - Jwe jwe = new Jwe(new JweHeader(h64), e64, c64, i64); + Jwe jwe = new Jwe(new JweHeader(h64), e64.getBytes(), c64.getBytes(), i64); return jwe; diff --git a/openid-connect-common/src/main/java/org/mitre/jwk/model/EC.java b/openid-connect-common/src/main/java/org/mitre/jwk/model/EC.java index c24bdd037..254b39767 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwk/model/EC.java +++ b/openid-connect-common/src/main/java/org/mitre/jwk/model/EC.java @@ -10,12 +10,8 @@ import java.security.spec.InvalidKeySpecException; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.ECNamedCurveTable; -import org.bouncycastle.jce.provider.JCEECPublicKey; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; -import org.bouncycastle.math.ec.ECPoint; import com.google.gson.JsonObject; diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java new file mode 100644 index 000000000..d0a8ac835 --- /dev/null +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java @@ -0,0 +1,41 @@ +package org.mitre.jwt.encryption; + +import java.security.NoSuchAlgorithmException; + +import org.mitre.jwe.model.Jwe; +import org.mitre.jwt.signer.impl.HmacSigner; +import org.mitre.jwt.signer.impl.RsaSigner; + +public abstract class AbstractJweEncrypter implements JwtEncrypter { + + @Override + public Jwe encrypt(Jwe jwe) { + + jwe.setCiphertext(encryptClaims(jwe)); + jwe.setEncryptedKey(encryptKey(jwe)); + + String alg = jwe.getHeader().getAlgorithm(); + if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) { + RsaSigner rsaSigner = new RsaSigner(); + try { + jwe = (Jwe) rsaSigner.sign(jwe); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){ + HmacSigner hmacSigner = new HmacSigner(); + try { + jwe = (Jwe) hmacSigner.sign(jwe); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + throw new IllegalArgumentException("Not a valid signing algorithm"); + } + + return jwe; + } + +} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtEncrypter.java index 851664858..06fcdc184 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtEncrypter.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JwtEncrypter.java @@ -1,123 +1,14 @@ package org.mitre.jwt.encryption; -import java.security.Key; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; +import org.mitre.jwe.model.Jwe; -import javax.crypto.Cipher; -import org.mitre.jwt.encryption.impl.HmacJwtEncrypter; -import org.mitre.jwt.encryption.impl.RsaJwtClaimsEncrypter; -import org.mitre.jwt.encryption.impl.RsaJwtEncrypter; -import org.mitre.jwt.model.EncryptedJwt; -import org.mitre.jwt.model.Jwt; -import org.mitre.jwt.model.JwtClaims; -import org.mitre.jwt.model.JwtHeader; - -public class JwtEncrypter { +public interface JwtEncrypter { - private Jwt jwt; + public byte[] encryptKey(Jwe jwe); - private JwtHeader header; - - private JwtClaims claims; - - private String signature; - - private Key encryptedKey; - - private byte[] cipherText; - - public JwtEncrypter(Jwt jwt) { - setJwt(jwt); - header = jwt.getHeader(); - claims = jwt.getClaims(); - signature = jwt.getSignature(); - } + public byte[] encryptClaims(Jwe jwe); - public Jwt getJwt() { - return jwt; - } - - public void setJwt(Jwt jwt) { - this.jwt = jwt; - } - - public Key getEncryptecKey() { - return encryptedKey; - } - - public void setEncryptedKey(Key encryptedKey) { - this.encryptedKey = encryptedKey; - } - - public JwtHeader getHeader() { - return header; - } - - public void setHeader(JwtHeader 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; - } - - public Key getEncryptedKey(Jwt jwt){ - String alg = jwt.getHeader().getAlgorithm(); - RSAPublicKey pubKey = null; - RSAPrivateKey privateKey = null; - String passphrase = null; - - if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) { - RsaJwtEncrypter rsaEncrypter = new RsaJwtEncrypter(pubKey, privateKey); - encryptedKey = rsaEncrypter.createEncryptedKey(); - } else if (alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){ - HmacJwtEncrypter hmacEncrypter = new HmacJwtEncrypter(alg, passphrase.getBytes()); - encryptedKey = hmacEncrypter.createEncryptedKey(); - } else { - throw new IllegalArgumentException("Not a valid algorithm"); - } - - return encryptedKey; - - } - - public byte[] getCipherText(Jwt jwt) { - String alg = jwt.getHeader().getAlgorithm(); - RSAPublicKey pubKey = null; - - if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) { - RsaJwtClaimsEncrypter claimsEncrypter = new RsaJwtClaimsEncrypter(jwt.getClaims(), pubKey); - cipherText = claimsEncrypter.createCipherText(); - } else if (alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){ - - } else { - throw new IllegalArgumentException("Not a valid algorithm"); - } - - return cipherText; - - } - - public EncryptedJwt encryptJwt(Jwt jwt) { - - //EncryptedJwt jwe = new EncryptedJwt(header, encryptedKey, claims, signature); - - return null; - } - + public Jwe encrypt(Jwe jwe); } diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtDecrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtDecrypter.java deleted file mode 100644 index 8f4c9cfaa..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtDecrypter.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.mitre.jwt.encryption.impl; - -public class HmacJwtDecrypter { - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtEncrypter.java deleted file mode 100644 index f67188315..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/HmacJwtEncrypter.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.mitre.jwt.encryption.impl; - -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; - -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.SecretKeySpec; - -public class HmacJwtEncrypter { - - private byte[] passphrase; - private String algorithm; - private byte[] wrappedKey; - private PrivateKey privateKey; - private PublicKey publicKey; - - public HmacJwtEncrypter(String algorithm, byte[] passphraseAsBytes){ - setPassphrase(passphraseAsBytes); - } - - public byte[] getPassphrase() { - return passphrase; - } - - public void setPassphrase(byte[] passphrase) { - this.passphrase = passphrase; - } - - public String getAlgorithm() { - return algorithm; - } - - public void setAlgorithm(String algorithm) { - this.algorithm = algorithm; - } - - public byte[] getWrappedKey() { - return wrappedKey; - } - - public void setWrappedKey(byte[] wrappedKey) { - this.wrappedKey = wrappedKey; - } - - public Key createEncryptedKey() { - try { - Cipher cipher = Cipher.getInstance(algorithm); - - SecretKeySpec keySpec = new SecretKeySpec(passphrase, algorithm); - KeyFactory keyFactory = KeyFactory.getInstance(algorithm); - privateKey = keyFactory.generatePrivate(keySpec); - publicKey = keyFactory.generatePublic(keySpec); - - cipher.init(Cipher.WRAP_MODE, publicKey); - byte[] wrappedKey = cipher.wrap(privateKey); - - SecretKeySpec wrappedKeySpec = new SecretKeySpec(wrappedKey, algorithm); - privateKey = keyFactory.generatePrivate(wrappedKeySpec); - - } 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 (InvalidKeySpecException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return privateKey; - } - -} 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/RsaDecrypter.java new file mode 100644 index 000000000..0da26e270 --- /dev/null +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java @@ -0,0 +1,121 @@ +package org.mitre.jwt.encryption.impl; + +import java.security.InvalidKeyException; +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.model.JwtClaims; + +public class RsaDecrypter { + + private Jwe jwe; + + private PrivateKey privateKey; + + private PublicKey publicKey; + + public RsaDecrypter(Jwe jwe) { + setJwe(jwe); + } + + public Jwe getJwe() { + return jwe; + } + + public void setJwe(Jwe jwe) { + this.jwe = jwe; + } + + public PrivateKey getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(PrivateKey privateKey) { + this.privateKey = privateKey; + } + + public PublicKey getPublicKey() { + return publicKey; + } + + public void setPublicKey(PublicKey publicKey) { + this.publicKey = publicKey; + } + + public String decryptCipherText() { + Cipher cipher; + String clearTextString = null; + try { + + cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + 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; + + } + + public byte[] decryptEncryptionKey() { + Cipher cipher; + byte[] unencryptedKey = null; + + try { + + cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + unencryptedKey = 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 unencryptedKey; + } + + public Jwe decrypt(Jwe jwe) { + + jwe.setClaims(new JwtClaims(decryptCipherText())); + jwe.setEncryptedKey(decryptEncryptionKey()); + + return 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/RsaEncrypter.java new file mode 100644 index 000000000..8e1afc2c3 --- /dev/null +++ b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java @@ -0,0 +1,161 @@ +package org.mitre.jwt.encryption.impl; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +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.jwe.model.JweHeader; +import org.mitre.jwt.encryption.AbstractJweEncrypter; +import org.mitre.jwt.model.JwtClaims; + +public class RsaEncrypter extends AbstractJweEncrypter { + + private Jwe jwe; + + private JweHeader header; + + private JwtClaims claims; + + private String signature; + + private byte[] encryptedKey; + + private byte[] cipherText; + + public RsaEncrypter(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 byte[] getEncryptecKey() { + return encryptedKey; + } + + public void setEncryptedKey(byte[] encryptedKey) { + this.encryptedKey = encryptedKey; + } + + 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; + } + + public byte[] getCipherText() { + return cipherText; + } + + public void setCipherText(byte[] cipherText) { + this.cipherText = cipherText; + } + + @Override + public byte[] encryptKey(Jwe jwe){ + String alg = jwe.getHeader().getAlgorithm(); + RSAPublicKey publicKey = null; // TODO: placeholder + RSAPrivateKey privateKey = null; + + if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) { + Cipher cipher; + try { + cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + encryptedKey = cipher.doFinal(privateKey.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(); + } + + } else { + throw new IllegalArgumentException("Not a valid algorithm for encryption"); + } + + return encryptedKey; + + } + + @Override + public byte[] encryptClaims(Jwe jwe) { + String alg = jwe.getHeader().getAlgorithm(); + RSAPublicKey publicKey = null; // TODO: placeholder + + if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) { + Cipher cipher; + try { + cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + cipherText = cipher.doFinal(claims.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(); + } + } else { + throw new IllegalArgumentException("Not a valid algorithm for encryption"); + } + + return cipherText; + + } + +} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsDecrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsDecrypter.java deleted file mode 100644 index 02da7af94..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsDecrypter.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.mitre.jwt.encryption.impl; - -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; - -public class RsaJwtClaimsDecrypter { - - private byte[] cipherText; - private PrivateKey privateKey; - - public RsaJwtClaimsDecrypter(byte[] cipherText, PrivateKey privateKey) { - setCipherText(cipherText); - setPrivateKey(privateKey); - } - - public byte[] getCipherText() { - return cipherText; - } - - public void setCipherText(byte[] cipherText) { - this.cipherText = cipherText; - } - - public PrivateKey getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(PrivateKey privateKey) { - this.privateKey = privateKey; - } - - public String decryptCipherText() { - Cipher cipher; - String clearTextString = null; - try { - - cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.DECRYPT_MODE, privateKey); - byte[] clearText = cipher.doFinal(cipherText); - 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; - - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsEncrypter.java deleted file mode 100644 index 640802908..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtClaimsEncrypter.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.mitre.jwt.encryption.impl; - -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; - -import org.mitre.jwt.model.JwtClaims; - -public class RsaJwtClaimsEncrypter { - - private JwtClaims claims; - private PublicKey publicKey; - - public RsaJwtClaimsEncrypter(JwtClaims claims, PublicKey pubKey) { - setClaims(claims); - setPublicKey(pubKey); - } - - public JwtClaims getClaims() { - return claims; - } - - public void setClaims(JwtClaims claims) { - this.claims = claims; - } - - public PublicKey getPublicKey() { - return publicKey; - } - - public void setPublicKey(PublicKey publicKey) { - this.publicKey = publicKey; - } - - public byte[] createCipherText() { - Cipher cipher; - byte[] cipherText = null; - try { - cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.ENCRYPT_MODE, publicKey); - cipherText = cipher.doFinal(claims.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; - - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtEncrypter.java deleted file mode 100644 index 7e412b6a7..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaJwtEncrypter.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.mitre.jwt.encryption.impl; - -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.SecretKeySpec; - -public class RsaJwtEncrypter { - - private PublicKey publicKey; - private PrivateKey privateKey; - - public RsaJwtEncrypter(RSAPublicKey pubKey, RSAPrivateKey privateKey){ - setPublicKey(pubKey); - setPrivateKey(privateKey); - } - - public PublicKey getPublicKey() { - return publicKey; - } - - public void setPublicKey(PublicKey pubKey) { - this.publicKey = pubKey; - } - - public PrivateKey getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(PrivateKey privateKey) { - this.privateKey = privateKey; - } - - public Key createEncryptedKey() { - Cipher cipher; - try { - cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.ENCRYPT_MODE, publicKey); - byte[] wrappedKey = cipher.doFinal(privateKey.getEncoded()); - - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - SecretKeySpec keySpec = new SecretKeySpec(wrappedKey, "RSA"); - privateKey = keyFactory.generatePrivate(keySpec); - - } 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 (InvalidKeySpecException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (BadPaddingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return privateKey; - } - - - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/model/EncryptedJwt.java b/openid-connect-common/src/main/java/org/mitre/jwt/model/EncryptedJwt.java deleted file mode 100644 index b26e039c1..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/model/EncryptedJwt.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.mitre.jwt.model; - -import java.util.List; - -import org.mitre.jwt.model.JwtClaims; -import org.mitre.jwt.model.JwtHeader; - -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; - -public class EncryptedJwt { - - JwtHeader header; - - String encryptedKey; - - JwtClaims claims; - - String signature; - - public EncryptedJwt() { - this.header = new JwtHeader(); - this.encryptedKey = null; - this.claims = new JwtClaims(); - this.signature = null; - } - - public EncryptedJwt (JwtHeader header, String encryptedKey, JwtClaims claims, String signature){ - setHeader(header); - setEncryptedKey(encryptedKey); - setClaims(claims); - setSignature(signature); - } - - public String toString(EncryptedJwt jwe) { - return getHeader() + "." + getEncryptedKey() + "." + getClaims() + "." + getSignature(); - } - - public JwtHeader getHeader() { - return header; - } - - public void setHeader(JwtHeader header) { - this.header = header; - } - - public String getEncryptedKey() { - return encryptedKey; - } - - public void setEncryptedKey(String encryptedKey) { - this.encryptedKey = encryptedKey; - } - - 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; - } - - public static EncryptedJwt parse(String s) { - - // null string is a null token - if (s == null) { - return null; - } - - // split on the dots - List parts = Lists.newArrayList(Splitter.on(".").split(s)); - - if (parts.size() != 4) { - throw new IllegalArgumentException("Invalid Encrypted JWT format."); - } - - String h64 = parts.get(0); - String e64 = parts.get(1); - String c64 = parts.get(2); - String i64 = parts.get(3); - - EncryptedJwt jwt = new EncryptedJwt(new JwtHeader(h64), e64, new JwtClaims(c64), i64); - - return jwt; - - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java index aed3c8fb3..7614e7f78 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java @@ -16,7 +16,6 @@ package org.mitre.jwt.signer.service; import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; import java.util.Map; import org.mitre.jwt.model.Jwt; diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java index cf8dc9cb6..e408a3d4b 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java @@ -16,8 +16,6 @@ package org.mitre.jwt.signer.service.impl; import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -25,7 +23,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.mitre.jwt.model.Jwt; import org.mitre.jwt.signer.JwtSigner; -import org.mitre.jwt.signer.impl.RsaSigner; import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.openid.connect.config.ConfigurationPropertiesBean; import org.springframework.beans.factory.InitializingBean;