Repository: cxf Updated Branches: refs/heads/master f75fa599c -> bbeddfc82
Updating JWE test to default to 128 bit keys if 256 is not supported Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/bbeddfc8 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/bbeddfc8 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/bbeddfc8 Branch: refs/heads/master Commit: bbeddfc82ba8cb584fbebd271bfdc9a31e8e0829 Parents: f75fa59 Author: Sergey Beryozkin <[email protected]> Authored: Wed Jun 11 17:03:47 2014 +0100 Committer: Sergey Beryozkin <[email protected]> Committed: Wed Jun 11 17:03:47 2014 +0100 ---------------------------------------------------------------------- .../oauth2/jwe/AbstractJweEncryptor.java | 9 +++- .../oauth2/jwe/DirectKeyJweEncryptor.java | 3 +- .../rs/security/oauth2/jwe/RSAJweEncryptor.java | 10 +++-- .../oauth2/jwe/WrappedKeyJweEncryptor.java | 8 ++-- .../cxf/rs/security/oauth2/jwt/Algorithm.java | 23 +++++++---- .../rs/security/oauth2/jwt/JwtConstants.java | 2 + .../oauth2/jwe/JweCompactReaderWriterTest.java | 43 ++++++++++++++------ 7 files changed, 67 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/bbeddfc8/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java index 7ccbfc1..5805ebb 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java @@ -39,7 +39,9 @@ public abstract class AbstractJweEncryptor implements JweEncryptor { private int authTagLen = DEFAULT_AUTH_TAG_LENGTH; protected AbstractJweEncryptor(SecretKey cek, byte[] iv) { - this(new JweHeaders(Algorithm.toJwtName(cek.getAlgorithm())), cek.getEncoded(), iv); + this(new JweHeaders(Algorithm.toJwtName(cek.getAlgorithm(), + cek.getEncoded().length * 8)), + cek.getEncoded(), iv); } protected AbstractJweEncryptor(JweHeaders headers, byte[] cek, byte[] iv) { this.headers = headers; @@ -75,7 +77,10 @@ public abstract class AbstractJweEncryptor implements JweEncryptor { protected abstract byte[] getEncryptedContentEncryptionKey(byte[] theCek); - protected String getContentEncryptionAlgo() { + protected String getContentEncryptionAlgoJwt() { + return headers.getContentEncryptionAlgorithm(); + } + protected String getContentEncryptionAlgoJava() { return Algorithm.toJavaName(headers.getContentEncryptionAlgorithm()); } http://git-wip-us.apache.org/repos/asf/cxf/blob/bbeddfc8/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryptor.java index 8872d81..7f1b59d 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryptor.java @@ -24,7 +24,8 @@ import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; public class DirectKeyJweEncryptor extends AbstractJweEncryptor { public DirectKeyJweEncryptor(SecretKey cek, byte[] iv) { - this(new JweHeaders(Algorithm.toJwtName(cek.getAlgorithm())), cek.getEncoded(), iv); + this(new JweHeaders(Algorithm.toJwtName(cek.getAlgorithm(), + cek.getEncoded().length * 8)), cek.getEncoded(), iv); } public DirectKeyJweEncryptor(JweHeaders headers, byte[] cek, byte[] iv) { super(headers, cek, iv); http://git-wip-us.apache.org/repos/asf/cxf/blob/bbeddfc8/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java index 7739379..e0974f1 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java @@ -27,7 +27,7 @@ import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersWriter; public class RSAJweEncryptor extends WrappedKeyJweEncryptor { public RSAJweEncryptor(RSAPublicKey publicKey, String contentEncryptionAlgo) { - super(new JweHeaders(Algorithm.RSA_OAEP_ALGO.getJwtName(), + super(new JweHeaders(Algorithm.RSA_OAEP.getJwtName(), contentEncryptionAlgo), publicKey); } public RSAJweEncryptor(RSAPublicKey publicKey, JweHeaders headers, byte[] cek, byte[] iv) { @@ -36,11 +36,13 @@ public class RSAJweEncryptor extends WrappedKeyJweEncryptor { public RSAJweEncryptor(RSAPublicKey publicKey, SecretKey secretKey, String secretKeyJwtAlgorithm, byte[] iv) { this(publicKey, - new JweHeaders(Algorithm.RSA_OAEP_ALGO.getJwtName(), secretKeyJwtAlgorithm), - secretKey.getEncoded(), iv, DEFAULT_AUTH_TAG_LENGTH, true); + new JweHeaders(Algorithm.RSA_OAEP.getJwtName(), secretKeyJwtAlgorithm), + secretKey != null ? secretKey.getEncoded() : null, iv, DEFAULT_AUTH_TAG_LENGTH, true); } public RSAJweEncryptor(RSAPublicKey publicKey, SecretKey secretKey, byte[] iv) { - this(publicKey, secretKey, Algorithm.toJwtName(secretKey.getAlgorithm()), iv); + this(publicKey, secretKey, + Algorithm.toJwtName(secretKey.getAlgorithm(), + secretKey.getEncoded().length * 8), iv); } public RSAJweEncryptor(RSAPublicKey publicKey, JweHeaders headers, byte[] cek, byte[] iv, http://git-wip-us.apache.org/repos/asf/cxf/blob/bbeddfc8/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryptor.java index ad6b905..6f9154a 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryptor.java @@ -48,8 +48,10 @@ public class WrappedKeyJweEncryptor extends AbstractJweEncryptor { protected byte[] getContentEncryptionKey() { byte[] theCek = super.getContentEncryptionKey(); if (theCek == null) { - String algo = getContentEncryptionAlgo(); - theCek = CryptoUtils.getSecretKey(algo, Algorithm.valueOf(algo).getKeySizeBits()).getEncoded(); + String algoJava = getContentEncryptionAlgoJava(); + String algoJwt = getContentEncryptionAlgoJwt(); + theCek = CryptoUtils.getSecretKey(Algorithm.stripAlgoProperties(algoJava), + Algorithm.valueOf(algoJwt).getKeySizeBits()).getEncoded(); } return theCek; } @@ -58,7 +60,7 @@ public class WrappedKeyJweEncryptor extends AbstractJweEncryptor { if (!wrap) { return CryptoUtils.encryptBytes(theCek, cekEncryptionKey, secretKeyProperties); } else { - return CryptoUtils.wrapSecretKey(theCek, getContentEncryptionAlgo(), cekEncryptionKey, + return CryptoUtils.wrapSecretKey(theCek, getContentEncryptionAlgoJava(), cekEncryptionKey, secretKeyProperties.getKeyAlgo()); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/bbeddfc8/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java index 8e30195..c6c7afc 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java @@ -36,9 +36,11 @@ public enum Algorithm { SHA512withRSA(JwtConstants.RS_SHA_512_ALGO, 512), // Key Encryption - RSA_OAEP_ALGO(JwtConstants.RSA_OAEP_ALGO, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", -1), + RSA_OAEP(JwtConstants.RSA_OAEP_ALGO, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", -1), // Content Encryption - A256GCM_ALGO(JwtConstants.A256GCM_ALGO, "AES/GCM/NoPadding", 256); + A128GCM(JwtConstants.A128GCM_ALGO, "AES/GCM/NoPadding", 128), + A192GCM(JwtConstants.A192GCM_ALGO, "AES/GCM/NoPadding", 192), + A256GCM(JwtConstants.A256GCM_ALGO, "AES/GCM/NoPadding", 256); public static final String HMAC_SHA_256_JAVA = "HmacSHA256"; public static final String HMAC_SHA_384_JAVA = "HmacSHA384"; @@ -50,7 +52,7 @@ public enum Algorithm { public static final String RSA_OAEP_256_ALGO_JAVA = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"; public static final String RSA_1_5_ALGO_JAVA = "RSA/ECB/PKCS1Padding"; public static final String AES_ALGO_JAVA = "AES"; - public static final String A256GCM_ALGO_JAVA = "AES/GCM/NoPadding"; + public static final String AES_GCM_ALGO_JAVA = "AES/GCM/NoPadding"; private static final Map<String, String> JAVA_TO_JWT_NAMES; private static final Map<String, String> JWT_TO_JAVA_NAMES; @@ -65,8 +67,6 @@ public enum Algorithm { JAVA_TO_JWT_NAMES.put(RSA_OAEP_ALGO_JAVA, JwtConstants.RSA_OAEP_ALGO); JAVA_TO_JWT_NAMES.put(RSA_OAEP_256_ALGO_JAVA, JwtConstants.RSA_OAEP_256_ALGO); JAVA_TO_JWT_NAMES.put(RSA_1_5_ALGO_JAVA, JwtConstants.RSA_1_5_ALGO); - JAVA_TO_JWT_NAMES.put(A256GCM_ALGO_JAVA, JwtConstants.A256GCM_ALGO); - JAVA_TO_JWT_NAMES.put(AES_ALGO_JAVA, JwtConstants.A256GCM_ALGO); JWT_TO_JAVA_NAMES = new HashMap<String, String>(); JWT_TO_JAVA_NAMES.put(JwtConstants.HMAC_SHA_256_ALGO, HMAC_SHA_256_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.HMAC_SHA_384_ALGO, HMAC_SHA_384_JAVA); @@ -77,7 +77,9 @@ public enum Algorithm { JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_OAEP_ALGO, RSA_OAEP_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_OAEP_256_ALGO, RSA_OAEP_256_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_1_5_ALGO, RSA_1_5_ALGO_JAVA); - JWT_TO_JAVA_NAMES.put(JwtConstants.A256GCM_ALGO, A256GCM_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A256GCM_ALGO, AES_GCM_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A192GCM_ALGO, AES_GCM_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A128GCM_ALGO, AES_GCM_ALGO_JAVA); } private final String jwtName; private final String javaName; @@ -108,8 +110,13 @@ public enum Algorithm { return keySizeBits; } - public static String toJwtName(String javaName) { - return JAVA_TO_JWT_NAMES.get(javaName); + public static String toJwtName(String javaName, int keyBitSize) { + //TODO: perhaps a key should be a name+keysize pair + String name = JAVA_TO_JWT_NAMES.get(javaName); + if (name == null && javaName.startsWith(AES_ALGO_JAVA)) { + name = "A" + keyBitSize + "GCM"; + } + return name; } public static String toJavaName(String jwtName) { return JWT_TO_JAVA_NAMES.get(jwtName); http://git-wip-us.apache.org/repos/asf/cxf/blob/bbeddfc8/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java index b26f526..545cd6e 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java @@ -60,6 +60,8 @@ public final class JwtConstants { public static final String RSA_OAEP_256_ALGO = "RSA-OAEP-256"; public static final String RSA_1_5_ALGO = "RSA1_5"; + public static final String A128GCM_ALGO = "A128GCM"; + public static final String A192GCM_ALGO = "A192GCM"; public static final String A256GCM_ALGO = "A256GCM"; private JwtConstants() { http://git-wip-us.apache.org/repos/asf/cxf/blob/bbeddfc8/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java index fa8bdc2..1ac3e6a 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java @@ -27,7 +27,6 @@ import javax.crypto.SecretKey; import org.apache.cxf.rs.security.oauth2.jws.JwsCompactReaderWriterTest; import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; -import org.apache.cxf.rs.security.oauth2.jwt.JwtConstants; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -64,7 +63,7 @@ public class JweCompactReaderWriterTest extends Assert { public static void registerBouncyCastleIfNeeded() throws Exception { try { // Java 8 apparently has it - Cipher.getInstance(Algorithm.A256GCM_ALGO_JAVA); + Cipher.getInstance(Algorithm.AES_GCM_ALGO_JAVA); } catch (Throwable t) { // Oracle Java 7 Security.addProvider(new BouncyCastleProvider()); @@ -78,32 +77,42 @@ public class JweCompactReaderWriterTest extends Assert { @Test public void testEncryptDecryptSpecExample() throws Exception { final String specPlainText = "The true sign of intelligence is not knowledge but imagination."; - String jweContent = encryptContent(specPlainText); + String jweContent = encryptContent(specPlainText, true); decrypt(jweContent, specPlainText); } @Test public void testDirectKeyEncryptDecrypt() throws Exception { final String specPlainText = "The true sign of intelligence is not knowledge but imagination."; - String jweContent = encryptContentDirect(specPlainText); + SecretKey key = createSecretKey(true); + String jweContent = encryptContentDirect(key, specPlainText); - decryptDirect(jweContent, specPlainText); + decryptDirect(key, jweContent, specPlainText); } @Test public void testEncryptDecryptJwsToken() throws Exception { - String jweContent = encryptContent(JwsCompactReaderWriterTest.ENCODED_TOKEN_SIGNED_BY_MAC); + String jweContent = encryptContent(JwsCompactReaderWriterTest.ENCODED_TOKEN_SIGNED_BY_MAC, false); decrypt(jweContent, JwsCompactReaderWriterTest.ENCODED_TOKEN_SIGNED_BY_MAC); } - private String encryptContent(String content) throws Exception { + private String encryptContent(String content, boolean createIfException) throws Exception { RSAPublicKey publicKey = CryptoUtils.getRSAPublicKey(RSA_MODULUS_ENCODED, RSA_PUBLIC_EXPONENT_ENCODED); - SecretKey key = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY, "AES"); - RSAJweEncryptor encryptor = new RSAJweEncryptor(publicKey, key, JwtConstants.A256GCM_ALGO, INIT_VECTOR); + SecretKey key = createSecretKey(createIfException); + String jwtKeyName = null; + if (key == null) { + // the encryptor will generate it + jwtKeyName = Algorithm.A128GCM.getJwtName(); + } else { + jwtKeyName = Algorithm.toJwtName(key.getAlgorithm(), key.getEncoded().length * 8); + } + RSAJweEncryptor encryptor = new RSAJweEncryptor(publicKey, + key, + jwtKeyName, + INIT_VECTOR); return encryptor.encryptText(content); } - private String encryptContentDirect(String content) throws Exception { - SecretKey key = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY, "AES"); + private String encryptContentDirect(SecretKey key, String content) throws Exception { DirectKeyJweEncryptor encryptor = new DirectKeyJweEncryptor(key, INIT_VECTOR); return encryptor.encryptText(content); } @@ -113,11 +122,19 @@ public class JweCompactReaderWriterTest extends Assert { String decryptedText = decryptor.decrypt(jweContent).getContentText(); assertEquals(decryptedText, plainContent); } - private void decryptDirect(String jweContent, String plainContent) throws Exception { - SecretKey key = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY, "AES"); + private void decryptDirect(SecretKey key, String jweContent, String plainContent) throws Exception { DirectKeyJweDecryptor decryptor = new DirectKeyJweDecryptor(key); String decryptedText = decryptor.decrypt(jweContent).getContentText(); assertEquals(decryptedText, plainContent); } + private SecretKey createSecretKey(boolean createIfException) throws Exception { + SecretKey key = null; + if (Cipher.getMaxAllowedKeyLength("AES") > 128) { + key = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY, "AES"); + } else if (createIfException) { + key = CryptoUtils.createSecretKeySpec(CryptoUtils.generateSecureRandomBytes(128 / 8), "AES"); + } + return key; + } }
