Repository: cxf Updated Branches: refs/heads/master 16172e3d1 -> 8ea1ea3f8
Finalizing JWE EDCH direct code for now Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/8ea1ea3f Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/8ea1ea3f Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/8ea1ea3f Branch: refs/heads/master Commit: 8ea1ea3f82df3fd5a08b74fca48393ff3c86f7e4 Parents: 16172e3 Author: Sergey Beryozkin <[email protected]> Authored: Mon Jan 5 17:50:40 2015 +0300 Committer: Sergey Beryozkin <[email protected]> Committed: Mon Jan 5 17:50:40 2015 +0300 ---------------------------------------------------------------------- .../jose/jwe/AbstractJweEncryption.java | 22 ++--- .../jose/jwe/DirectKeyDecryptionAlgorithm.java | 43 --------- .../jose/jwe/DirectKeyEncryptionAlgorithm.java | 34 -------- .../jose/jwe/DirectKeyJweDecryption.java | 32 ++++++- .../jose/jwe/DirectKeyJweEncryption.java | 24 ++++- .../jose/jwe/EcdhDirectKeyJweDecryption.java | 59 +++++++++++++ .../jose/jwe/EcdhDirectKeyJweEncryption.java | 92 ++++++++++++++++++++ .../jose/jwe/JweCompactReaderWriterTest.java | 61 ++++--------- 8 files changed, 231 insertions(+), 136 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java index 02de81a..02db4e0 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java @@ -54,9 +54,11 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { this.keyEncryptionAlgo = keyEncryptionAlgo; this.contentEncryptionAlgo = contentEncryptionAlgo; } - + protected ContentEncryptionAlgorithm getContentEncryptionAlgorithm() { + return contentEncryptionAlgo; + } protected AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) { - return contentEncryptionAlgo.getAlgorithmParameterSpec(theIv); + return getContentEncryptionAlgorithm().getAlgorithmParameterSpec(theIv); } protected byte[] getContentEncryptionKey() { @@ -75,11 +77,11 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { } protected byte[] getProvidedContentEncryptionKey() { - return contentEncryptionAlgo.getContentEncryptionKey(headers); + return getContentEncryptionAlgorithm().getContentEncryptionKey(headers); } protected byte[] getEncryptedContentEncryptionKey(byte[] theCek) { - return keyEncryptionAlgo.getEncryptedContentEncryptionKey(headers, theCek); + return getKeyEncryptionAlgo().getEncryptedContentEncryptionKey(headers, theCek); } protected String getContentEncryptionAlgoJwt() { @@ -89,7 +91,7 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { return Algorithm.toJavaName(getContentEncryptionAlgoJwt()); } protected byte[] getAAD(JweHeaders theHeaders) { - return contentEncryptionAlgo.getAdditionalAuthenticationData(writer.headersToJson(theHeaders)); + return getContentEncryptionAlgorithm().getAdditionalAuthenticationData(writer.headersToJson(theHeaders)); } public String encrypt(byte[] content, JweHeaders jweHeaders) { JweEncryptionInternal state = getInternalState(jweHeaders); @@ -118,11 +120,11 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { } @Override public String getKeyAlgorithm() { - return keyEncryptionAlgo.getAlgorithm(); + return getKeyEncryptionAlgo().getAlgorithm(); } @Override public String getContentAlgorithm() { - return contentEncryptionAlgo.getAlgorithm(); + return getContentEncryptionAlgorithm().getAlgorithm(); } @Override public JweEncryptionState createJweEncryptionState(JweHeaders jweHeaders) { @@ -154,7 +156,7 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { KeyProperties keyProps = new KeyProperties(contentEncryptionAlgoJavaName); keyProps.setCompressionSupported(compressionRequired(headers)); - byte[] theIv = contentEncryptionAlgo.getInitVector(); + byte[] theIv = getContentEncryptionAlgorithm().getInitVector(); AlgorithmParameterSpec specParams = getAlgorithmParameterSpec(theIv); keyProps.setAlgoSpec(specParams); byte[] jweContentEncryptionKey = getEncryptedContentEncryptionKey(theCek); @@ -162,9 +164,9 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { JweHeaders theHeaders = headers; if (jweHeaders != null) { if (jweHeaders.getKeyEncryptionAlgorithm() != null - && !keyEncryptionAlgo.getAlgorithm().equals(jweHeaders.getKeyEncryptionAlgorithm()) + && !getKeyAlgorithm().equals(jweHeaders.getKeyEncryptionAlgorithm()) || jweHeaders.getAlgorithm() != null - && !contentEncryptionAlgo.getAlgorithm().equals(jweHeaders.getAlgorithm())) { + && !getContentAlgorithm().equals(jweHeaders.getAlgorithm())) { throw new SecurityException(); } theHeaders = new JweHeaders(theHeaders.asMap()); http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java deleted file mode 100644 index 88a48ca..0000000 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ -package org.apache.cxf.rs.security.jose.jwe; - -import java.security.Key; - -public class DirectKeyDecryptionAlgorithm implements KeyDecryptionAlgorithm { - private byte[] contentDecryptionKey; - public DirectKeyDecryptionAlgorithm(Key contentDecryptionKey) { - this(contentDecryptionKey.getEncoded()); - } - public DirectKeyDecryptionAlgorithm(byte[] contentDecryptionKey) { - this.contentDecryptionKey = contentDecryptionKey; - } - @Override - public byte[] getDecryptedContentEncryptionKey(JweCompactConsumer consumer) { - byte[] encryptedCEK = consumer.getEncryptedContentEncryptionKey(); - if (encryptedCEK != null && encryptedCEK.length > 0) { - throw new SecurityException(); - } - return contentDecryptionKey; - } - @Override - public String getAlgorithm() { - return null; - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java deleted file mode 100644 index 6714c3c..0000000 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ -package org.apache.cxf.rs.security.jose.jwe; - - -public class DirectKeyEncryptionAlgorithm implements KeyEncryptionAlgorithm { - public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) { - if (headers.getKeyEncryptionAlgorithm() != null) { - throw new SecurityException(); - } - return new byte[0]; - } - - @Override - public String getAlgorithm() { - return null; - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java index 6c822ea..cd351ef 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java @@ -30,9 +30,37 @@ public class DirectKeyJweDecryption extends AbstractJweDecryption { public DirectKeyJweDecryption(Key contentDecryptionKey, JoseHeadersReader reader, ContentDecryptionAlgorithm cipherProps) { - super(reader, + this(reader, new DirectKeyDecryptionAlgorithm(contentDecryptionKey), cipherProps); } - + protected DirectKeyJweDecryption(JoseHeadersReader reader, + DirectKeyDecryptionAlgorithm direct, + ContentDecryptionAlgorithm cipherProps) { + super(reader, direct, cipherProps); + } + protected static class DirectKeyDecryptionAlgorithm implements KeyDecryptionAlgorithm { + private byte[] contentDecryptionKey; + public DirectKeyDecryptionAlgorithm(Key contentDecryptionKey) { + this(contentDecryptionKey.getEncoded()); + } + public DirectKeyDecryptionAlgorithm(byte[] contentDecryptionKey) { + this.contentDecryptionKey = contentDecryptionKey; + } + @Override + public byte[] getDecryptedContentEncryptionKey(JweCompactConsumer consumer) { + validateKeyEncryptionKey(consumer); + return contentDecryptionKey; + } + @Override + public String getAlgorithm() { + return null; + } + protected void validateKeyEncryptionKey(JweCompactConsumer consumer) { + byte[] encryptedCEK = consumer.getEncryptedContentEncryptionKey(); + if (encryptedCEK != null && encryptedCEK.length > 0) { + throw new SecurityException(); + } + } + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java index b343cf4..ada89a8 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java @@ -25,7 +25,12 @@ public class DirectKeyJweEncryption extends AbstractJweEncryption { this(new JweHeaders(ceAlgo.getAlgorithm()), ceAlgo); } public DirectKeyJweEncryption(JweHeaders headers, ContentEncryptionAlgorithm ceAlgo) { - super(headers, ceAlgo, new DirectKeyEncryptionAlgorithm()); + this(headers, ceAlgo, new DirectKeyEncryptionAlgorithm()); + } + protected DirectKeyJweEncryption(JweHeaders headers, + ContentEncryptionAlgorithm ceAlgo, + DirectKeyEncryptionAlgorithm direct) { + super(headers, ceAlgo, direct); } protected byte[] getProvidedContentEncryptionKey() { return validateCek(super.getProvidedContentEncryptionKey()); @@ -38,4 +43,21 @@ public class DirectKeyJweEncryption extends AbstractJweEncryption { } return cek; } + protected static class DirectKeyEncryptionAlgorithm implements KeyEncryptionAlgorithm { + public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) { + if (headers.getKeyEncryptionAlgorithm() != null) { + throw new SecurityException(); + } + return new byte[0]; + } + protected void checkKeyEncryptionAlgorithm(JweHeaders headers) { + if (headers.getKeyEncryptionAlgorithm() != null) { + throw new SecurityException(); + } + } + @Override + public String getAlgorithm() { + return null; + } + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweDecryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweDecryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweDecryption.java new file mode 100644 index 0000000..01b4ffb --- /dev/null +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweDecryption.java @@ -0,0 +1,59 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.cxf.rs.security.jose.jwe; + +import java.security.interfaces.ECPrivateKey; + +import org.apache.cxf.rs.security.jose.JoseUtils; +import org.apache.cxf.rs.security.jose.jwa.Algorithm; +import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; +import org.apache.cxf.rs.security.jose.jwk.JwkUtils; + + +public class EcdhDirectKeyJweDecryption extends DirectKeyJweDecryption { + public EcdhDirectKeyJweDecryption(ECPrivateKey privateKey, String supportedCtAlgo) { + super(null, + new EcdhDirectKeyDecryptionAlgorithm(privateKey), + new AesGcmContentDecryptionAlgorithm(supportedCtAlgo)); + } + protected static class EcdhDirectKeyDecryptionAlgorithm extends DirectKeyDecryptionAlgorithm { + private ECPrivateKey privateKey; + public EcdhDirectKeyDecryptionAlgorithm(ECPrivateKey privateKey) { + super((byte[])null); + this.privateKey = privateKey; + } + @Override + public byte[] getDecryptedContentEncryptionKey(JweCompactConsumer consumer) { + super.validateKeyEncryptionKey(consumer); + + return getDecryptedContentEncryptionKeyFromHeaders(consumer.getJweHeaders()); + } + + protected byte[] getDecryptedContentEncryptionKeyFromHeaders(JweHeaders headers) { + Algorithm jwtAlgo = Algorithm.valueOf(headers.getContentEncryptionAlgorithm()); + 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 JweUtils.getECDHKey(privateKey, JwkUtils.toECPublicKey(publicJwk), + apuBytes, apvBytes, jwtAlgo.getJwtName(), jwtAlgo.getKeySizeBits()); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweEncryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweEncryption.java new file mode 100644 index 0000000..1943444 --- /dev/null +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhDirectKeyJweEncryption.java @@ -0,0 +1,92 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.cxf.rs.security.jose.jwe; + +import java.security.KeyPair; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; + +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.rs.security.jose.JoseConstants; +import org.apache.cxf.rs.security.jose.jwa.Algorithm; +import org.apache.cxf.rs.security.jose.jwk.JwkUtils; + + +public class EcdhDirectKeyJweEncryption extends DirectKeyJweEncryption { + public EcdhDirectKeyJweEncryption(ECPublicKey peerPublicKey, + String curve, + String apuString, + String apvString, + String ctAlgo) { + super(new JweHeaders(ctAlgo), + new EcdhAesGcmContentEncryptionAlgorithm(peerPublicKey, + curve, + toBytes(apuString), + toBytes(apvString), + ctAlgo), + new EcdhDirectKeyEncryptionAlgorithm()); + } + private static byte[] toBytes(String str) { + return str == null ? null : StringUtils.toBytesUTF8(str); + } + protected static class EcdhDirectKeyEncryptionAlgorithm extends DirectKeyEncryptionAlgorithm { + protected void checkKeyEncryptionAlgorithm(JweHeaders headers) { + headers.setKeyEncryptionAlgorithm(JoseConstants.ECDH_ES_DIRECT_ALGO); + } + } + protected static class EcdhAesGcmContentEncryptionAlgorithm extends AesGcmContentEncryptionAlgorithm { + private ECPublicKey peerPublicKey; + private String ecurve; + private byte[] apuBytes; + private byte[] apvBytes; + public EcdhAesGcmContentEncryptionAlgorithm(ECPublicKey peerPublicKey, + String curve, + byte[] apuBytes, + byte[] apvBytes, + String ctAlgo) { + super(ctAlgo); + this.peerPublicKey = peerPublicKey; + this.ecurve = curve; + this.apuBytes = apuBytes; + this.apvBytes = apvBytes; + } + public byte[] getContentEncryptionKey(JweHeaders headers) { + KeyPair pair = CryptoUtils.generateECKeyPair(ecurve); + ECPublicKey publicKey = (ECPublicKey)pair.getPublic(); + ECPrivateKey privateKey = (ECPrivateKey)pair.getPrivate(); + return doGetContentEncryptionKey(headers, publicKey, privateKey); + } + protected byte[] doGetContentEncryptionKey(JweHeaders headers, + ECPublicKey publicKey, + ECPrivateKey privateKey) { + Algorithm jwtAlgo = Algorithm.valueOf(super.getAlgorithm()); + + headers.setHeader("apu", Base64UrlUtility.encode(apuBytes)); + headers.setHeader("apv", Base64UrlUtility.encode(apvBytes)); + headers.setJsonWebKey("epv", JwkUtils.fromECPublicKey(publicKey, ecurve)); + + return JweUtils.getECDHKey(privateKey, peerPublicKey, apuBytes, apvBytes, + jwtAlgo.getJwtName(), jwtAlgo.getKeySizeBits()); + + } + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/8ea1ea3f/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 649e927..5a18267 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 @@ -23,20 +23,15 @@ 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 javax.crypto.Cipher; 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.rs.security.jose.JoseConstants; -import org.apache.cxf.rs.security.jose.JoseHeaders; -import org.apache.cxf.rs.security.jose.JoseUtils; import org.apache.cxf.rs.security.jose.jwa.Algorithm; import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; -import org.apache.cxf.rs.security.jose.jwk.JwkUtils; import org.apache.cxf.rs.security.jose.jws.JwsCompactReaderWriterTest; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -123,54 +118,28 @@ public class JweCompactReaderWriterTest extends Assert { String decryptedText = decryption.decrypt(jweContent).getContentText(); assertEquals(specPlainText, decryptedText); } + @Test public void testECDHESDirectKeyEncryption() throws Exception { - ECPrivateKey alicePrivateKey = + ECPrivateKey bobPrivateKey = CryptoUtils.getECPrivateKey(JsonWebKey.EC_CURVE_P256, - "0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo"); - ECPublicKey alicePublicKey = - CryptoUtils.getECPublicKey(JsonWebKey.EC_CURVE_P256, - "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0", - "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"); + "VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw"); - ECPublicKey bobPublicKey = + final ECPublicKey bobPublicKey = CryptoUtils.getECPublicKey(JsonWebKey.EC_CURVE_P256, "weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ", "e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck"); - - byte[] apuBytes = StringUtils.toBytesUTF8("Alice"); - byte[] apvBytes = StringUtils.toBytesUTF8("Bob"); - - byte[] derivedKey = JweUtils.getECDHKey(alicePrivateKey, bobPublicKey, apuBytes, apvBytes, - Algorithm.A128GCM.getJwtName(), Algorithm.A128GCM.getKeySizeBits()); - assertEquals("VqqN6vgjbSBcIijNcacQGg", Base64UrlUtility.encode(derivedKey)); - - JweHeaders headers = new JweHeaders(); - headers.setAlgorithm(JoseConstants.ECDH_ES_DIRECT_ALGO); - headers.setContentEncryptionAlgorithm(Algorithm.A128GCM.getJwtName()); - headers.setHeader("apu", Base64UrlUtility.encode(apuBytes)); - headers.setHeader("apv", Base64UrlUtility.encode(apvBytes)); - headers.setJsonWebKey("epv", JwkUtils.fromECPublicKey(alicePublicKey, JsonWebKey.EC_CURVE_P256)); - - byte[] derivedKey2 = calculateDerivedKeyFromHeaders(headers, - headers.getContentEncryptionAlgorithm(), - Algorithm.A128GCM.getKeySizeBits()); - assertTrue(Arrays.equals(derivedKey2, derivedKey)); - } - private static byte[] calculateDerivedKeyFromHeaders(JoseHeaders headers, - String algoName, - int algoKeyLen) { - 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 JweUtils.getECDHKey(bobPrivateKey, JwkUtils.toECPublicKey(publicJwk), - apuBytes, apvBytes, algoName, algoKeyLen); + JweEncryptionProvider jweOut = + new EcdhDirectKeyJweEncryption(bobPublicKey, + JsonWebKey.EC_CURVE_P256, + "Alice", + "Bob", + Algorithm.A128GCM.getJwtName()); + + String jweOutput = jweOut.encrypt("Hello".getBytes(), null); + JweDecryptionProvider jweIn = + new EcdhDirectKeyJweDecryption(bobPrivateKey, Algorithm.A128GCM.getJwtName()); + assertEquals("Hello", jweIn.decrypt(jweOutput).getContentText()); } @Test public void testEncryptDecryptRSA15WrapA128CBCHS256() throws Exception {
