You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2014/12/30 18:06:22 UTC
cxf git commit: Creating some utility ECDH code
Repository: cxf
Updated Branches:
refs/heads/master a3bf2a80b -> 632cb29d8
Creating some utility ECDH code
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/632cb29d
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/632cb29d
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/632cb29d
Branch: refs/heads/master
Commit: 632cb29d89ea23bca39791ef774db5c53b752a09
Parents: a3bf2a8
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Tue Dec 30 17:06:04 2014 +0000
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Tue Dec 30 17:06:04 2014 +0000
----------------------------------------------------------------------
.../cxf/rs/security/jose/JoseConstants.java | 4 +
.../cxf/rs/security/jose/jwe/JweUtils.java | 86 +++++++++++++++++-
.../jose/jwe/JweCompactReaderWriterTest.java | 94 +++-----------------
3 files changed, 100 insertions(+), 84 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/632cb29d/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
index 39b86c7..e131147 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
@@ -71,6 +71,10 @@ public final class JoseConstants {
public static final String ECDH_ES_DIRECT_ALGO = "ECDH-ES";
+ public static final String ECDH_ES_A128KW_ALGO = "ECDH-ES+A128KW";
+ public static final String ECDH_ES_A192KW_ALGO = "ECDH-ES+A192KW";
+ public static final String ECDH_ES_A256KW_ALGO = "ECDH-ES+A256KW";
+
public static final String PBES2_HS256_A128KW_ALGO = "PBES2-HS256+A128KW";
public static final String PBES2_HS384_A192KW_ALGO = "PBES2-HS384+A192KW";
public static final String PBES2_HS512_A256KW_ALGO = "PBES2-HS512+A256KW";
http://git-wip-us.apache.org/repos/asf/cxf/blob/632cb29d/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
index ec0a69c..62ecbb0 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
@@ -18,13 +18,20 @@
*/
package org.apache.cxf.rs.security.jose.jwe;
+import java.nio.ByteBuffer;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Properties;
+import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.crypto.MessageDigestUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.rs.security.jose.JoseConstants;
@@ -354,11 +361,88 @@ public final class JweUtils {
getContentDecryptionAlgorithm(contentDecryptionAlgo));
}
}
-
public static boolean validateCriticalHeaders(JoseHeaders headers) {
//TODO: Validate JWE specific constraints
return JoseUtils.validateCriticalHeaders(headers);
}
+ public static byte[] getECDHKey(JsonWebKey privateKey,
+ JsonWebKey peerPublicKey,
+ byte[] partyUInfo,
+ byte[] partyVInfo,
+ String algoName,
+ int algoKeyBitLen) {
+ return getECDHKey(JwkUtils.toECPrivateKey(privateKey),
+ JwkUtils.toECPublicKey(peerPublicKey),
+ partyUInfo, partyVInfo, algoName, algoKeyBitLen);
+ }
+ public static byte[] getECDHKey(ECPrivateKey privateKey,
+ ECPublicKey peerPublicKey,
+ byte[] partyUInfo,
+ byte[] partyVInfo,
+ String algoName,
+ int algoKeyBitLen) {
+ byte[] keyZ = generateKeyZ(privateKey, peerPublicKey);
+ return calculateDerivedKey(keyZ, algoName, partyUInfo, partyVInfo, algoKeyBitLen);
+ }
+
+ private static byte[] calculateDerivedKey(byte[] keyZ,
+ String algoName,
+ byte[] apuBytes,
+ byte[] apvBytes,
+ int algoKeyBitLen) {
+ final byte[] emptyPartyInfo = new byte[4];
+
+ if (apuBytes != null && apvBytes != null && Arrays.equals(apuBytes, apvBytes)) {
+ throw new SecurityException();
+ }
+ byte[] algorithmId = concatenateDatalenAndData(StringUtils.toBytesASCII(algoName));
+ byte[] partyUInfo = apuBytes == null ? emptyPartyInfo : concatenateDatalenAndData(apuBytes);
+ byte[] partyVInfo = apvBytes == null ? emptyPartyInfo : concatenateDatalenAndData(apvBytes);
+ byte[] suppPubInfo = datalenToBytes(algoKeyBitLen);
+
+ byte[] otherInfo = new byte[algorithmId.length
+ + partyUInfo.length
+ + partyVInfo.length
+ + suppPubInfo.length];
+ System.arraycopy(algorithmId, 0, otherInfo, 0, algorithmId.length);
+ System.arraycopy(partyUInfo, 0, otherInfo, algorithmId.length, partyUInfo.length);
+ System.arraycopy(partyVInfo, 0, otherInfo, algorithmId.length + partyUInfo.length, partyVInfo.length);
+ System.arraycopy(suppPubInfo, 0, otherInfo, algorithmId.length + partyUInfo.length + partyVInfo.length,
+ suppPubInfo.length);
+
+
+ byte[] concatKDF = new byte[36 + otherInfo.length];
+ concatKDF[3] = 1;
+ System.arraycopy(keyZ, 0, concatKDF, 4, keyZ.length);
+ System.arraycopy(otherInfo, 0, concatKDF, 36, otherInfo.length);
+ try {
+ byte[] round1Hash = MessageDigestUtils.createDigest(concatKDF, MessageDigestUtils.ALGO_SHA_256);
+ return Arrays.copyOf(round1Hash, algoKeyBitLen / 8);
+ } catch (Exception ex) {
+ throw new SecurityException(ex);
+ }
+ }
+ private static byte[] generateKeyZ(ECPrivateKey privateKey, ECPublicKey publicKey) {
+ try {
+ KeyAgreement ka = KeyAgreement.getInstance("ECDH");
+ ka.init(privateKey);
+ ka.doPhase(publicKey, true);
+ return ka.generateSecret();
+ } catch (Exception ex) {
+ throw new SecurityException(ex);
+ }
+ }
+ private static byte[] concatenateDatalenAndData(byte[] bytesASCII) {
+ final byte[] datalen = datalenToBytes(bytesASCII.length);
+ byte[] all = new byte[4 + bytesASCII.length];
+ System.arraycopy(datalen, 0, all, 0, 4);
+ System.arraycopy(bytesASCII, 0, all, 4, bytesASCII.length);
+ return all;
+ }
+ private static byte[] datalenToBytes(int len) {
+ ByteBuffer buf = ByteBuffer.allocate(4);
+ return buf.putInt(len).array();
+ }
private static JweHeaders prepareJweHeaders(String keyEncryptionAlgo,
String contentEncryptionAlgo,
String compression) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/632cb29d/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweCompactReaderWriterTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweCompactReaderWriterTest.java b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweCompactReaderWriterTest.java
index 9204f3a..649e927 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweCompactReaderWriterTest.java
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweCompactReaderWriterTest.java
@@ -18,7 +18,6 @@
*/
package org.apache.cxf.rs.security.jose.jwe;
-import java.nio.ByteBuffer;
import java.security.Security;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
@@ -27,13 +26,11 @@ import java.security.interfaces.RSAPublicKey;
import java.util.Arrays;
import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import org.apache.cxf.common.util.Base64UrlUtility;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.common.util.crypto.CryptoUtils;
-import org.apache.cxf.common.util.crypto.MessageDigestUtils;
import org.apache.cxf.rs.security.jose.JoseConstants;
import org.apache.cxf.rs.security.jose.JoseHeaders;
import org.apache.cxf.rs.security.jose.JoseUtils;
@@ -141,15 +138,11 @@ public class JweCompactReaderWriterTest extends Assert {
"weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ",
"e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck");
- byte[] keyZ = generateKeyZ(alicePrivateKey, bobPublicKey);
byte[] apuBytes = StringUtils.toBytesUTF8("Alice");
byte[] apvBytes = StringUtils.toBytesUTF8("Bob");
- byte[] derivedKey = calculateDerivedKey(keyZ,
- Algorithm.A128GCM.getJwtName(),
- apuBytes,
- apvBytes,
- Algorithm.A128GCM.getKeySizeBits());
+ byte[] derivedKey = JweUtils.getECDHKey(alicePrivateKey, bobPublicKey, apuBytes, apvBytes,
+ Algorithm.A128GCM.getJwtName(), Algorithm.A128GCM.getKeySizeBits());
assertEquals("VqqN6vgjbSBcIijNcacQGg", Base64UrlUtility.encode(derivedKey));
JweHeaders headers = new JweHeaders();
@@ -159,90 +152,25 @@ public class JweCompactReaderWriterTest extends Assert {
headers.setHeader("apv", Base64UrlUtility.encode(apvBytes));
headers.setJsonWebKey("epv", JwkUtils.fromECPublicKey(alicePublicKey, JsonWebKey.EC_CURVE_P256));
- ECPrivateKey bobPrivateKey =
- CryptoUtils.getECPrivateKey(JsonWebKey.EC_CURVE_P256,
- "VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw");
- byte[] derivedKey2 = calculateDerivedKeyFromHeaders(bobPrivateKey,
- headers,
+ byte[] derivedKey2 = calculateDerivedKeyFromHeaders(headers,
headers.getContentEncryptionAlgorithm(),
Algorithm.A128GCM.getKeySizeBits());
assertTrue(Arrays.equals(derivedKey2, derivedKey));
}
- private static byte[] calculateDerivedKeyFromHeaders(ECPrivateKey privateKey,
- JoseHeaders headers,
+ private static byte[] calculateDerivedKeyFromHeaders(JoseHeaders headers,
String algoName,
int algoKeyLen) {
- JsonWebKey ephemeralJwk = headers.getJsonWebKey("epv");
- byte[] keyZ = generateKeyZ(privateKey, JwkUtils.toECPublicKey(ephemeralJwk));
+ ECPrivateKey bobPrivateKey =
+ CryptoUtils.getECPrivateKey(JsonWebKey.EC_CURVE_P256,
+ "VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw");
+
+ JsonWebKey publicJwk = headers.getJsonWebKey("epv");
String apuHeader = (String)headers.getHeader("apu");
byte[] apuBytes = apuHeader == null ? null : JoseUtils.decode(apuHeader);
String apvHeader = (String)headers.getHeader("apv");
byte[] apvBytes = apvHeader == null ? null : JoseUtils.decode(apvHeader);
-
- return calculateDerivedKey(keyZ,
- algoName,
- apuBytes,
- apvBytes,
- algoKeyLen);
- }
-
- private static byte[] calculateDerivedKey(byte[] keyZ,
- String algoName,
- byte[] apuBytes,
- byte[] apvBytes,
- int algoKeyBitLen) {
- final byte[] emptyPartyInfo = new byte[4];
-
- if (apuBytes != null && apvBytes != null && Arrays.equals(apuBytes, apvBytes)) {
- throw new SecurityException();
- }
- byte[] algorithmId = concatenateDatalenAndData(StringUtils.toBytesASCII(algoName));
- byte[] partyUInfo = apuBytes == null ? emptyPartyInfo : concatenateDatalenAndData(apuBytes);
- byte[] partyVInfo = apvBytes == null ? emptyPartyInfo : concatenateDatalenAndData(apvBytes);
- byte[] suppPubInfo = datalenToBytes(algoKeyBitLen);
-
- byte[] otherInfo = new byte[algorithmId.length
- + partyUInfo.length
- + partyVInfo.length
- + suppPubInfo.length];
- System.arraycopy(algorithmId, 0, otherInfo, 0, algorithmId.length);
- System.arraycopy(partyUInfo, 0, otherInfo, algorithmId.length, partyUInfo.length);
- System.arraycopy(partyVInfo, 0, otherInfo, algorithmId.length + partyUInfo.length, partyVInfo.length);
- System.arraycopy(suppPubInfo, 0, otherInfo, algorithmId.length + partyUInfo.length + partyVInfo.length,
- suppPubInfo.length);
-
-
- byte[] concatKDF = new byte[36 + otherInfo.length];
- concatKDF[3] = 1;
- System.arraycopy(keyZ, 0, concatKDF, 4, keyZ.length);
- System.arraycopy(otherInfo, 0, concatKDF, 36, otherInfo.length);
- try {
- byte[] round1Hash = MessageDigestUtils.createDigest(concatKDF, MessageDigestUtils.ALGO_SHA_256);
- return Arrays.copyOf(round1Hash, algoKeyBitLen / 8);
- } catch (Exception ex) {
- throw new SecurityException(ex);
- }
- }
- private static byte[] generateKeyZ(ECPrivateKey privateKey, ECPublicKey publicKey) {
- try {
- KeyAgreement ka = KeyAgreement.getInstance("ECDH");
- ka.init(privateKey);
- ka.doPhase(publicKey, true);
- return ka.generateSecret();
- } catch (Exception ex) {
- throw new SecurityException(ex);
- }
- }
- private static byte[] concatenateDatalenAndData(byte[] bytesASCII) {
- final byte[] datalen = datalenToBytes(bytesASCII.length);
- byte[] all = new byte[4 + bytesASCII.length];
- System.arraycopy(datalen, 0, all, 0, 4);
- System.arraycopy(bytesASCII, 0, all, 4, bytesASCII.length);
- return all;
- }
- private static byte[] datalenToBytes(int len) {
- ByteBuffer buf = ByteBuffer.allocate(4);
- return buf.putInt(len).array();
+ return JweUtils.getECDHKey(bobPrivateKey, JwkUtils.toECPublicKey(publicJwk),
+ apuBytes, apvBytes, algoName, algoKeyLen);
}
@Test
public void testEncryptDecryptRSA15WrapA128CBCHS256() throws Exception {