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/10/06 19:26:01 UTC

[08/10] [CXF-5944] Finalizing the current round of refactorings with introducing a dedicated rt rs security module, idea from Luigi Lo Iacono

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionAlgorithm.java
new file mode 100644
index 0000000..ccf7ce7
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionAlgorithm.java
@@ -0,0 +1,24 @@
+/**
+ * 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 interface ContentDecryptionAlgorithm extends ContentEncryptionCipherProperties {
+    byte[] getEncryptedSequence(JweHeaders headers, byte[] cipher, byte[] authTag);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.java
new file mode 100644
index 0000000..07b370e
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.java
@@ -0,0 +1,27 @@
+/**
+ * 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 interface ContentEncryptionAlgorithm extends ContentEncryptionCipherProperties {
+    String getAlgorithm();
+    byte[] getInitVector();
+    byte[] getContentEncryptionKey(JweHeaders headers);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
new file mode 100644
index 0000000..54da6fd
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
@@ -0,0 +1,27 @@
+/**
+ * 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.spec.AlgorithmParameterSpec;
+
+
+public interface ContentEncryptionCipherProperties {
+    byte[] getAdditionalAuthenticationData(String headersJson);
+    AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] iv);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/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
new file mode 100644
index 0000000..c1803c6
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
@@ -0,0 +1,39 @@
+/**
+ * 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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/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
new file mode 100644
index 0000000..6714c3c
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
@@ -0,0 +1,34 @@
+/**
+ * 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/9c053334/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
new file mode 100644
index 0000000..6c822ea
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
@@ -0,0 +1,38 @@
+/**
+ * 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;
+
+import org.apache.cxf.rs.security.jose.JoseHeadersReader;
+
+public class DirectKeyJweDecryption extends AbstractJweDecryption {
+    public DirectKeyJweDecryption(Key contentDecryptionKey, 
+                                  ContentDecryptionAlgorithm cipherProps) {
+        this(contentDecryptionKey, null, cipherProps);
+    }
+    public DirectKeyJweDecryption(Key contentDecryptionKey, 
+                                  JoseHeadersReader reader,
+                                  ContentDecryptionAlgorithm cipherProps) {    
+        super(reader, 
+              new DirectKeyDecryptionAlgorithm(contentDecryptionKey),
+              cipherProps);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/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
new file mode 100644
index 0000000..b343cf4
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
@@ -0,0 +1,41 @@
+/**
+ * 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 DirectKeyJweEncryption extends AbstractJweEncryption {
+    
+    public DirectKeyJweEncryption(ContentEncryptionAlgorithm ceAlgo) {
+        this(new JweHeaders(ceAlgo.getAlgorithm()), ceAlgo);
+    }
+    public DirectKeyJweEncryption(JweHeaders headers, ContentEncryptionAlgorithm ceAlgo) {
+        super(headers, ceAlgo, new DirectKeyEncryptionAlgorithm());
+    }
+    protected byte[] getProvidedContentEncryptionKey() {
+        return validateCek(super.getProvidedContentEncryptionKey());
+    }
+    private static byte[] validateCek(byte[] cek) {
+        if (cek == null) {
+            // to prevent the cek from being auto-generated which 
+            // does not make sense for the direct key case
+            throw new NullPointerException("CEK must not be null");
+        }
+        return cek;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java
new file mode 100644
index 0000000..7794102
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java
@@ -0,0 +1,113 @@
+/**
+ * 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.io.UnsupportedEncodingException;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.rs.security.jose.JoseHeaders;
+import org.apache.cxf.rs.security.jose.JoseHeadersReader;
+import org.apache.cxf.rs.security.jose.JoseHeadersReaderWriter;
+
+
+public class JweCompactConsumer {
+    private String headersJson;
+    private byte[] encryptedCEK;
+    private byte[] initVector;
+    private byte[] encryptedContent;
+    private byte[] authTag;
+    private JweHeaders jweHeaders;
+    public JweCompactConsumer(String jweContent) {
+        this(jweContent, new JoseHeadersReaderWriter());
+    }
+    public JweCompactConsumer(String jweContent, JoseHeadersReader reader) {
+        String[] parts = jweContent.split("\\.");
+        if (parts.length != 5) {
+            throw new SecurityException("5 JWE parts are expected");
+        }
+        try {
+            headersJson = new String(Base64UrlUtility.decode(parts[0]));
+            encryptedCEK = Base64UrlUtility.decode(parts[1]);
+            initVector = Base64UrlUtility.decode(parts[2]);
+            
+            encryptedContent = Base64UrlUtility.decode(parts[3]);
+            authTag = Base64UrlUtility.decode(parts[4]);
+            JoseHeaders joseHeaders = reader.fromJsonHeaders(headersJson);
+            if (joseHeaders.getHeaderUpdateCount() != null) { 
+                throw new SecurityException();
+            }
+            jweHeaders = new JweHeaders(joseHeaders);
+            
+        } catch (Base64Exception ex) {
+            throw new SecurityException(ex);
+        }
+    }
+    
+    public String getDecodedJsonHeaders() {
+        return headersJson;
+    }
+    
+    public JweHeaders getJweHeaders() {
+        return jweHeaders;
+    }
+    
+    public byte[] getEncryptedContentEncryptionKey() {
+        return encryptedCEK;
+    }
+    
+    public byte[] getContentDecryptionCipherInitVector() {
+        return initVector;
+    }
+    
+    public byte[] getContentEncryptionCipherAAD() {
+        return JweHeaders.toCipherAdditionalAuthData(headersJson);
+    }
+    
+    public byte[] getEncryptionAuthenticationTag() {
+        return authTag;
+    }
+    
+    public byte[] getEncryptedContent() {
+        return encryptedContent;
+    }
+    
+    public byte[] getEncryptedContentWithAuthTag() {
+        return getCipherWithAuthTag(encryptedContent, authTag);
+    }
+    
+    public static byte[] getCipherWithAuthTag(byte[] cipher, byte[] authTag) {
+        byte[] encryptedContentWithTag = new byte[cipher.length + authTag.length];
+        System.arraycopy(cipher, 0, encryptedContentWithTag, 0, cipher.length);
+        System.arraycopy(authTag, 0, encryptedContentWithTag, cipher.length, authTag.length);  
+        return encryptedContentWithTag;
+    }
+    
+    public byte[] getDecryptedContent(JweDecryptionProvider decryption) {
+        return decryption.decrypt(this);
+    }
+    public String getDecryptedContentText(JweDecryptionProvider decryption) {
+        try {
+            return new String(getDecryptedContent(decryption), "UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new SecurityException(ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java
new file mode 100644
index 0000000..176081b
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java
@@ -0,0 +1,156 @@
+/**
+ * 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.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.rs.security.jose.JoseHeadersReaderWriter;
+import org.apache.cxf.rs.security.jose.JoseHeadersWriter;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter;
+
+
+public class JweCompactProducer {
+    private StringBuilder jweContentBuilder;
+    private String encodedEncryptedContent;
+    private String encodedAuthTag;
+    public JweCompactProducer(JweHeaders headers,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentNoTag,
+                       byte[] authenticationTag) {    
+        this(headers, null, encryptedContentEncryptionKey, 
+             cipherInitVector, encryptedContentNoTag, authenticationTag);
+    }
+    
+    public JweCompactProducer(JweHeaders headers,
+                       JoseHeadersWriter writer,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentNoTag,
+                       byte[] authenticationTag) {
+        this(getHeadersJson(headers, writer),
+             encryptedContentEncryptionKey,
+             cipherInitVector,
+             encryptedContentNoTag,
+             authenticationTag);
+    }
+    public JweCompactProducer(String headersJson,
+                              byte[] encryptedContentEncryptionKey,
+                              byte[] cipherInitVector,
+                              byte[] encryptedContentNoTag,
+                              byte[] authenticationTag) {
+        jweContentBuilder = startJweContent(new StringBuilder(), headersJson, 
+                                  encryptedContentEncryptionKey, cipherInitVector);
+        this.encodedEncryptedContent = Base64UrlUtility.encode(encryptedContentNoTag);
+        this.encodedAuthTag = Base64UrlUtility.encode(authenticationTag);
+       
+    }
+    
+    public JweCompactProducer(JweHeaders headers,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentWithTag,
+                       int authTagLengthBits) {    
+        this(headers, null, encryptedContentEncryptionKey, 
+             cipherInitVector, encryptedContentWithTag, authTagLengthBits);
+    }
+    public JweCompactProducer(JweHeaders headers,
+                       JoseHeadersWriter writer,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentWithTag,
+                       int authTagLengthBits) {
+        jweContentBuilder = startJweContent(new StringBuilder(), headers, writer,
+                                   encryptedContentEncryptionKey, cipherInitVector);
+        this.encodedEncryptedContent = Base64UrlUtility.encodeChunk(
+            encryptedContentWithTag, 
+            0, 
+            encryptedContentWithTag.length - authTagLengthBits / 8);
+        this.encodedAuthTag = Base64UrlUtility.encodeChunk(
+            encryptedContentWithTag, 
+            encryptedContentWithTag.length - authTagLengthBits / 8, 
+            authTagLengthBits / 8);
+        
+    }
+    public static String startJweContent(JweHeaders headers,
+                                                JoseHeadersWriter writer, 
+                                                byte[] encryptedContentEncryptionKey,
+                                                byte[] cipherInitVector) {
+        return startJweContent(new StringBuilder(), 
+                               headers, writer, encryptedContentEncryptionKey, cipherInitVector).toString();       
+    }
+    public static StringBuilder startJweContent(StringBuilder sb,
+                                        JweHeaders headers,
+                                        JoseHeadersWriter writer, 
+                                        byte[] encryptedContentEncryptionKey,
+                                        byte[] cipherInitVector) {
+        return startJweContent(sb, 
+                               getHeadersJson(headers, writer), 
+                               encryptedContentEncryptionKey, 
+                               cipherInitVector);
+    }
+    private static String getHeadersJson(JweHeaders headers,
+                                         JoseHeadersWriter writer) {
+        writer = writer == null ? new JoseHeadersReaderWriter() : writer;
+        return writer.headersToJson(headers);
+        
+    }
+    public static StringBuilder startJweContent(StringBuilder sb,
+                                                String headersJson,
+                                                byte[] encryptedContentEncryptionKey,
+                                                byte[] cipherInitVector) {
+        String encodedHeaders = Base64UrlUtility.encode(headersJson);
+        String encodedContentEncryptionKey = Base64UrlUtility.encode(encryptedContentEncryptionKey);
+        String encodedInitVector = Base64UrlUtility.encode(cipherInitVector);
+        sb.append(encodedHeaders)
+            .append('.')
+            .append(encodedContentEncryptionKey == null ? "" : encodedContentEncryptionKey)
+            .append('.')
+            .append(encodedInitVector == null ? "" : encodedInitVector)
+            .append('.');
+        return sb;
+    }
+    
+    public static void startJweContent(OutputStream os,
+                                       JweHeaders headers,
+                                       JoseHeadersWriter writer, 
+                                       byte[] encryptedContentEncryptionKey,
+                                       byte[] cipherInitVector) throws IOException {
+        writer = writer == null ? new JwtTokenReaderWriter() : writer;
+        byte[] jsonBytes = writer.headersToJson(headers).getBytes("UTF-8");
+        Base64UrlUtility.encodeAndStream(jsonBytes, 0, jsonBytes.length, os);
+        byte[] dotBytes = new byte[]{'.'};
+        os.write(dotBytes);
+        Base64UrlUtility.encodeAndStream(encryptedContentEncryptionKey, 0, 
+                                         encryptedContentEncryptionKey.length, os);
+        os.write(dotBytes);
+        Base64UrlUtility.encodeAndStream(cipherInitVector, 0, cipherInitVector.length, os);
+        os.write(dotBytes);         
+    }
+    
+    public String getJweContent() {
+        return jweContentBuilder.append(encodedEncryptedContent)
+                 .append('.')
+                 .append(encodedAuthTag)
+                 .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java
new file mode 100644
index 0000000..f3cf255
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java
@@ -0,0 +1,43 @@
+/**
+ * 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.io.UnsupportedEncodingException;
+
+public class JweDecryptionOutput {
+    private JweHeaders headers;
+    private byte[] content;
+    public JweDecryptionOutput(JweHeaders headers, byte[] content) {
+        this.headers = headers;
+        this.content = content;
+    }
+    public JweHeaders getHeaders() {
+        return headers;
+    }
+    public byte[] getContent() {
+        return content;
+    }
+    public String getContentText() {
+        try {
+            return new String(getContent(), "UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new SecurityException(ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionProvider.java
new file mode 100644
index 0000000..d20401b
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionProvider.java
@@ -0,0 +1,26 @@
+/**
+ * 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 interface JweDecryptionProvider {
+    JweDecryptionOutput decrypt(String jweContent);
+    byte[] decrypt(JweCompactConsumer consumer);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.java
new file mode 100644
index 0000000..5b9afee
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.java
@@ -0,0 +1,26 @@
+/**
+ * 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 interface JweEncryptionProvider {
+    String encrypt(byte[] jweContent, String contentType);
+    JweEncryptionState createJweEncryptionState(String contentType);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java
new file mode 100644
index 0000000..0732250
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java
@@ -0,0 +1,63 @@
+/**
+ * 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 javax.crypto.Cipher;
+
+public class JweEncryptionState {
+    private Cipher cipher;
+    private JweHeaders headers;
+    private byte[] contentEncryptionKey;
+    private byte[] iv;
+    private boolean compressionSupported;
+    private AuthenticationTagProducer authTagProducer;
+    
+    public JweEncryptionState(Cipher cipher, 
+                              JweHeaders headers, 
+                              byte[] contentEncryptionKey, 
+                              byte[] iv, 
+                              AuthenticationTagProducer authTagProducer,
+                              boolean compressionSupported) {
+        this.cipher = cipher;
+        this.headers = headers;
+        this.contentEncryptionKey = contentEncryptionKey;
+        this.iv = iv;
+        this.authTagProducer = authTagProducer;
+        this.compressionSupported = compressionSupported;
+    }
+    public Cipher getCipher() {
+        return cipher;
+    }
+    public JweHeaders getHeaders() {
+        return headers;
+    }
+    public byte[] getContentEncryptionKey() {
+        return contentEncryptionKey;
+    }
+    public byte[] getIv() {
+        return iv;
+    }
+    public boolean isCompressionSupported() {
+        return compressionSupported;
+    }
+    public AuthenticationTagProducer getAuthTagProducer() {
+        return authTagProducer;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
new file mode 100644
index 0000000..f0e6d37
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
@@ -0,0 +1,106 @@
+/**
+ * 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.io.UnsupportedEncodingException;
+import java.util.Map;
+
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.rs.security.jose.JoseConstants;
+import org.apache.cxf.rs.security.jose.JoseHeaders;
+import org.apache.cxf.rs.security.jose.JoseHeadersWriter;
+
+
+
+
+public class JweHeaders extends JoseHeaders {
+    
+    public JweHeaders() {
+    }
+    
+    public JweHeaders(JoseHeaders headers) {
+        super(headers.asMap());
+    }
+    
+    public JweHeaders(Map<String, Object> values) {
+        super(values);
+    }
+    public JweHeaders(String keyEncAlgo, String ctEncAlgo) {
+        this(keyEncAlgo, ctEncAlgo, false);
+    }
+    public JweHeaders(String ctEncAlgo) {
+        this(null, ctEncAlgo, false);
+    }
+    public JweHeaders(String ctEncAlgo, boolean deflate) {
+        this(null, ctEncAlgo, deflate);
+    }
+    public JweHeaders(String keyEncAlgo, String ctEncAlgo, boolean deflate) {
+        init(keyEncAlgo, ctEncAlgo, deflate);
+    }
+    private void init(String keyEncAlgo, String ctEncAlgo, boolean deflate) {
+        if (keyEncAlgo != null) {
+            setKeyEncryptionAlgorithm(keyEncAlgo);    
+        }
+        setContentEncryptionAlgorithm(ctEncAlgo);
+        if (deflate) {
+            setZipAlgorithm(JoseConstants.DEFLATE_ZIP_ALGORITHM);
+        }
+    }
+    
+    public void setKeyEncryptionAlgorithm(String type) {
+        super.setAlgorithm(type);
+    }
+    
+    public String getKeyEncryptionAlgorithm() {
+        return super.getAlgorithm();
+    }
+    
+    public void setContentEncryptionAlgorithm(String type) {
+        setHeader(JoseConstants.JWE_HEADER_CONTENT_ENC_ALGORITHM, type);
+    }
+    
+    public String getContentEncryptionAlgorithm() {
+        return (String)getHeader(JoseConstants.JWE_HEADER_CONTENT_ENC_ALGORITHM);
+    }
+    
+    public void setZipAlgorithm(String type) {
+        setHeader(JoseConstants.JWE_HEADER_ZIP_ALGORITHM, type);
+    }
+    
+    public String getZipAlgorithm() {
+        return (String)getHeader(JoseConstants.JWE_HEADER_ZIP_ALGORITHM);
+    }
+    
+    @Override
+    public JoseHeaders setHeader(String name, Object value) {
+        return (JoseHeaders)super.setHeader(name, value);
+    }
+    public byte[] toCipherAdditionalAuthData(JoseHeadersWriter writer) { 
+        return toCipherAdditionalAuthData(writer.headersToJson(this));
+    }
+    public static byte[] toCipherAdditionalAuthData(String headersJson) { 
+        try {
+            String base64UrlHeadersInJson = Base64UrlUtility.encode(headersJson.getBytes("UTF-8"));
+            return base64UrlHeadersInJson.getBytes("US-ASCII");
+        } catch (UnsupportedEncodingException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweOutputStream.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweOutputStream.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweOutputStream.java
new file mode 100644
index 0000000..c6462f1
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweOutputStream.java
@@ -0,0 +1,145 @@
+/**
+ * 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.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+import javax.crypto.Cipher;
+
+import org.apache.cxf.common.util.Base64UrlUtility;
+
+public class JweOutputStream extends FilterOutputStream {
+    private Cipher encryptingCipher;
+    private int blockSize;
+    private AuthenticationTagProducer authTagProducer;
+    private byte[] lastRawDataChunk;
+    private byte[] lastEncryptedDataChunk;
+    private boolean flushed;
+    public JweOutputStream(OutputStream out, 
+                           Cipher encryptingCipher, 
+                           AuthenticationTagProducer authTagProducer) {
+        super(out);
+        this.encryptingCipher = encryptingCipher;
+        this.blockSize = encryptingCipher.getBlockSize(); 
+        this.authTagProducer = authTagProducer;
+    }
+
+    @Override
+    public void write(int value) throws IOException {
+        byte[] bytes = ByteBuffer.allocate(Integer.SIZE / 8).putInt(value).array();
+        write(bytes, 0, bytes.length);
+    }
+    
+    @Override
+    public void write(byte b[], int off, int len) throws IOException {
+        if (lastRawDataChunk != null) {
+            int remaining = blockSize - lastRawDataChunk.length;
+            int lenToCopy = remaining < len ? remaining : len;
+            lastRawDataChunk = newArray(lastRawDataChunk, 0, lastRawDataChunk.length, b, off, lenToCopy);
+            off = off + lenToCopy;
+            len -= lenToCopy;
+            if (lastRawDataChunk.length < blockSize) {
+                return;
+            } else {
+                encryptAndWrite(lastRawDataChunk, 0, lastRawDataChunk.length);
+                lastRawDataChunk = null;
+            }
+        } 
+        int offset = 0;
+        int chunkSize = blockSize > len ? blockSize : blockSize * (len / blockSize);
+        for (; offset + chunkSize <= len; offset += chunkSize, off += chunkSize) {
+            encryptAndWrite(b, off, chunkSize);
+        }
+        if (offset < len) {
+            lastRawDataChunk = newArray(b, off, len - offset);
+        }
+        
+    }
+    
+    private void encryptAndWrite(byte[] chunk, int off, int len) throws IOException {
+        byte[] encrypted = encryptingCipher.update(chunk, off, len);
+        if (authTagProducer != null) {
+            authTagProducer.update(encrypted, 0, encrypted.length);
+        }
+        encodeAndWrite(encrypted, 0, encrypted.length, false);
+    }
+    private void encodeAndWrite(byte[] encryptedChunk, int off, int len, boolean finalWrite) throws IOException {
+        byte[] theChunk = lastEncryptedDataChunk;
+        int lenToEncode = len;
+        if (theChunk != null) {
+            theChunk = newArray(theChunk, 0, theChunk.length, encryptedChunk, off, len);
+            lenToEncode = theChunk.length;
+            off = 0;
+        } else {
+            theChunk = encryptedChunk;
+        }
+        int rem = finalWrite ? 0 : lenToEncode % 3; 
+        Base64UrlUtility.encodeAndStream(theChunk, off, lenToEncode - rem, out);
+        
+        if (rem > 0) {
+            lastEncryptedDataChunk = newArray(theChunk, lenToEncode - rem, rem);
+        } else {
+            lastEncryptedDataChunk = null;
+        }
+    }
+    
+    @Override
+    public void flush() throws IOException {
+        if (flushed) {
+            return;
+        }
+        try {
+            byte[] finalBytes = lastRawDataChunk == null 
+                ? encryptingCipher.doFinal()
+                : encryptingCipher.doFinal(lastRawDataChunk, 0, lastRawDataChunk.length);
+            final int authTagLengthBits = 128;
+            if (authTagProducer != null) {
+                authTagProducer.update(finalBytes, 0, finalBytes.length);
+                encodeAndWrite(finalBytes, 0, finalBytes.length, true);
+            } else {
+                encodeAndWrite(finalBytes, 0, finalBytes.length - authTagLengthBits / 8, true);
+            }
+            out.write(new byte[]{'.'});
+            
+            if (authTagProducer == null) {
+                encodeAndWrite(finalBytes, finalBytes.length - authTagLengthBits / 8, authTagLengthBits / 8, true);
+            } else {
+                byte[] authTag = authTagProducer.getTag();
+                encodeAndWrite(authTag, 0, authTagLengthBits / 8, true);
+            }
+        } catch (Exception ex) {
+            throw new SecurityException();
+        }
+        flushed = true;
+    }
+    private byte[] newArray(byte[] src, int srcPos, int srcLen) {
+        byte[] buf = new byte[srcLen];
+        System.arraycopy(src, srcPos, buf, 0, srcLen);
+        return buf;
+    }
+    private byte[] newArray(byte[] src, int srcPos, int srcLen, byte[] src2, int srcPos2, int srcLen2) {
+        byte[] buf = new byte[srcLen + srcLen2];
+        System.arraycopy(src, srcPos, buf, 0, srcLen);
+        System.arraycopy(src2, srcPos2, buf, srcLen, srcLen2);
+        return buf;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/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
new file mode 100644
index 0000000..483ff52
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
@@ -0,0 +1,97 @@
+/**
+ * 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 javax.crypto.SecretKey;
+
+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 final class JweUtils {
+    private JweUtils() {
+        
+    }
+    public static KeyEncryptionAlgorithm getKeyEncryptionAlgorithm(JsonWebKey jwk) {
+        return getKeyEncryptionAlgorithm(jwk, null);
+    }
+    public static KeyEncryptionAlgorithm getKeyEncryptionAlgorithm(JsonWebKey jwk, String defaultAlgorithm) {
+        String keyEncryptionAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
+        KeyEncryptionAlgorithm keyEncryptionProvider = null;
+        if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) {
+            keyEncryptionProvider = new RSAOaepKeyEncryptionAlgorithm(JwkUtils.toRSAPublicKey(jwk), 
+                                                                      keyEncryptionAlgo);
+        } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) {
+            SecretKey key = JwkUtils.toSecretKey(jwk);
+            if (Algorithm.isAesKeyWrap(keyEncryptionAlgo)) {
+                keyEncryptionProvider = new AesWrapKeyEncryptionAlgorithm(key, keyEncryptionAlgo);
+            } else if (Algorithm.isAesGcmKeyWrap(keyEncryptionAlgo)) {
+                keyEncryptionProvider = new AesGcmWrapKeyEncryptionAlgorithm(key, keyEncryptionAlgo);
+            }
+        } else {
+            // TODO: support elliptic curve keys
+        }
+        return keyEncryptionProvider;
+    }
+    public static KeyDecryptionAlgorithm getKeyDecryptionAlgorithm(JsonWebKey jwk) {
+        return getKeyDecryptionAlgorithm(jwk, null);
+    }
+    public static KeyDecryptionAlgorithm getKeyDecryptionAlgorithm(JsonWebKey jwk, String defaultAlgorithm) {
+        String keyEncryptionAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
+        KeyDecryptionAlgorithm keyDecryptionProvider = null;
+        if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) {
+            keyDecryptionProvider = new RSAOaepKeyDecryptionAlgorithm(JwkUtils.toRSAPrivateKey(jwk), 
+                                                                      keyEncryptionAlgo);
+        } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) {
+            SecretKey key = JwkUtils.toSecretKey(jwk);
+            if (Algorithm.isAesKeyWrap(jwk.getAlgorithm())) {
+                keyDecryptionProvider = new AesWrapKeyDecryptionAlgorithm(key, keyEncryptionAlgo);
+            } else if (Algorithm.isAesGcmKeyWrap(jwk.getAlgorithm())) {
+                keyDecryptionProvider = new AesGcmWrapKeyDecryptionAlgorithm(key, keyEncryptionAlgo);
+            } 
+        } else {
+            // TODO: support elliptic curve keys
+        }
+        return keyDecryptionProvider;
+    }
+    public static ContentEncryptionAlgorithm getContentEncryptionAlgorithm(JsonWebKey jwk) {
+        return getContentEncryptionAlgorithm(jwk, null);
+    }
+    public static ContentEncryptionAlgorithm getContentEncryptionAlgorithm(JsonWebKey jwk, String defaultAlgorithm) {
+        String ctEncryptionAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
+        ContentEncryptionAlgorithm contentEncryptionProvider = null;
+        if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) {
+            SecretKey key = JwkUtils.toSecretKey(jwk);
+            if (Algorithm.isAesGcm(ctEncryptionAlgo)) {
+                contentEncryptionProvider = new AesGcmContentEncryptionAlgorithm(key, null, ctEncryptionAlgo);
+            }
+        }
+        return contentEncryptionProvider;
+    }
+    public static SecretKey getContentDecryptionSecretKey(JsonWebKey jwk) {
+        return getContentDecryptionSecretKey(jwk, null);
+    }
+    public static SecretKey getContentDecryptionSecretKey(JsonWebKey jwk, String defaultAlgorithm) {
+        String ctEncryptionAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
+        if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType()) && Algorithm.isAesGcm(ctEncryptionAlgo)) {
+            return JwkUtils.toSecretKey(jwk);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyDecryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..9932ab2
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyDecryptionAlgorithm.java
@@ -0,0 +1,24 @@
+/**
+ * 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 interface KeyDecryptionAlgorithm {
+    byte[] getDecryptedContentEncryptionKey(JweCompactConsumer consumer);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyEncryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..3885291
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/KeyEncryptionAlgorithm.java
@@ -0,0 +1,25 @@
+/**
+ * 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 interface KeyEncryptionAlgorithm {
+    String getAlgorithm();
+    byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] cek);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyDecryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..d338cdd
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyDecryptionAlgorithm.java
@@ -0,0 +1,54 @@
+/**
+ * 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 org.apache.cxf.common.util.Base64UrlUtility;
+
+public class PbesHmacAesWrapKeyDecryptionAlgorithm implements KeyDecryptionAlgorithm {
+    private byte[] password;
+    public PbesHmacAesWrapKeyDecryptionAlgorithm(String password) {    
+        this(PbesHmacAesWrapKeyEncryptionAlgorithm.stringToBytes(password));
+    }
+    public PbesHmacAesWrapKeyDecryptionAlgorithm(char[] password) {    
+        this(PbesHmacAesWrapKeyEncryptionAlgorithm.charsToBytes(password));
+    }
+    public PbesHmacAesWrapKeyDecryptionAlgorithm(byte[] password) {    
+        this.password = password;
+    }
+    @Override
+    public byte[] getDecryptedContentEncryptionKey(JweCompactConsumer consumer) {
+        byte[] saltInput = getDecodedBytes(consumer, "p2s");
+        int pbesCount = consumer.getJweHeaders().getIntegerHeader("p2c");
+        String keyAlgoJwt = consumer.getJweHeaders().getAlgorithm();
+        int keySize = PbesHmacAesWrapKeyEncryptionAlgorithm.getKeySize(keyAlgoJwt);
+        byte[] derivedKey = PbesHmacAesWrapKeyEncryptionAlgorithm
+            .createDerivedKey(keyAlgoJwt, keySize, password, saltInput, pbesCount);
+        KeyDecryptionAlgorithm aesWrap = new AesWrapKeyDecryptionAlgorithm(derivedKey);
+        return aesWrap.getDecryptedContentEncryptionKey(consumer);
+    }    
+    private byte[] getDecodedBytes(JweCompactConsumer consumer, String headerName) {
+        try {
+            Object headerValue = consumer.getJweHeaders().getHeader(headerName);
+            return Base64UrlUtility.decode(headerValue.toString());
+        } catch (Exception ex) {
+            throw new SecurityException(ex);
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..4697cad
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java
@@ -0,0 +1,173 @@
+/**
+ * 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.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.common.util.crypto.CryptoUtils;
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.digests.SHA256Digest;
+import org.bouncycastle.crypto.digests.SHA384Digest;
+import org.bouncycastle.crypto.digests.SHA512Digest;
+import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.bouncycastle.crypto.params.KeyParameter;
+
+public class PbesHmacAesWrapKeyEncryptionAlgorithm implements KeyEncryptionAlgorithm {
+    private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>(
+        Arrays.asList(Algorithm.PBES2_HS256_A128KW.getJwtName(),
+                      Algorithm.PBES2_HS384_A192KW.getJwtName(),
+                      Algorithm.PBES2_HS512_A256KW.getJwtName()));
+    private static final Map<String, Integer> PBES_HMAC_MAP;
+    private static final Map<String, String> PBES_AES_MAP;
+    private static final Map<String, Integer> DERIVED_KEY_SIZE_MAP;
+    static {
+        PBES_HMAC_MAP = new HashMap<String, Integer>();
+        PBES_HMAC_MAP.put(Algorithm.PBES2_HS256_A128KW.getJwtName(), 256);
+        PBES_HMAC_MAP.put(Algorithm.PBES2_HS384_A192KW.getJwtName(), 384);
+        PBES_HMAC_MAP.put(Algorithm.PBES2_HS512_A256KW.getJwtName(), 512);
+        
+        PBES_AES_MAP = new HashMap<String, String>();
+        PBES_AES_MAP.put(Algorithm.PBES2_HS256_A128KW.getJwtName(), Algorithm.A128KW.getJwtName());
+        PBES_AES_MAP.put(Algorithm.PBES2_HS384_A192KW.getJwtName(), Algorithm.A192KW.getJwtName());
+        PBES_AES_MAP.put(Algorithm.PBES2_HS512_A256KW.getJwtName(), Algorithm.A256KW.getJwtName());
+        
+        DERIVED_KEY_SIZE_MAP = new HashMap<String, Integer>();
+        DERIVED_KEY_SIZE_MAP.put(Algorithm.PBES2_HS256_A128KW.getJwtName(), 16);
+        DERIVED_KEY_SIZE_MAP.put(Algorithm.PBES2_HS384_A192KW.getJwtName(), 24);
+        DERIVED_KEY_SIZE_MAP.put(Algorithm.PBES2_HS512_A256KW.getJwtName(), 32);
+    }
+    
+    
+    private byte[] password;
+    private int pbesCount;
+    private String keyAlgoJwt;
+    public PbesHmacAesWrapKeyEncryptionAlgorithm(String password, String keyAlgoJwt) {
+        this(stringToBytes(password), keyAlgoJwt);
+    }
+    public PbesHmacAesWrapKeyEncryptionAlgorithm(String password, int pbesCount, String keyAlgoJwt) {
+        this(stringToBytes(password), pbesCount, keyAlgoJwt);
+    }
+    public PbesHmacAesWrapKeyEncryptionAlgorithm(char[] password, String keyAlgoJwt) {
+        this(password, 4096, keyAlgoJwt);
+    }
+    public PbesHmacAesWrapKeyEncryptionAlgorithm(char[] password, int pbesCount, String keyAlgoJwt) {
+        this(charsToBytes(password), pbesCount, keyAlgoJwt);
+    }
+    public PbesHmacAesWrapKeyEncryptionAlgorithm(byte[] password, String keyAlgoJwt) {
+        this(password, 4096, keyAlgoJwt);
+    }
+    public PbesHmacAesWrapKeyEncryptionAlgorithm(byte[] password, int pbesCount, String keyAlgoJwt) {
+        this.password = password;
+        this.keyAlgoJwt = validateKeyAlgorithm(keyAlgoJwt);
+        this.pbesCount = validatePbesCount(pbesCount);
+    }
+    
+    @Override
+    public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] cek) {
+        int keySize = getKeySize(keyAlgoJwt);
+        byte[] saltInput = CryptoUtils.generateSecureRandomBytes(keySize);
+        byte[] derivedKey = createDerivedKey(keyAlgoJwt, keySize, password, saltInput, pbesCount);
+        
+        headers.setHeader("p2s", Base64UrlUtility.encode(saltInput));
+        headers.setIntegerHeader("p2c", pbesCount);
+        
+        final String aesAlgoJwt = PBES_AES_MAP.get(keyAlgoJwt);
+        KeyEncryptionAlgorithm aesWrap = new AesWrapKeyEncryptionAlgorithm(derivedKey, aesAlgoJwt) {
+            protected void checkAlgorithms(JweHeaders headers) {
+                // complete
+            }
+            protected String getKeyEncryptionAlgoJava(JweHeaders headers) {
+                return Algorithm.AES_WRAP_ALGO_JAVA;
+            }
+        };
+        return aesWrap.getEncryptedContentEncryptionKey(headers, cek);
+        
+        
+    }
+    static int getKeySize(String keyAlgoJwt) {
+        return DERIVED_KEY_SIZE_MAP.get(keyAlgoJwt);
+    }
+    static byte[] createDerivedKey(String keyAlgoJwt, int keySize,
+                                   byte[] password, byte[] saltInput, int pbesCount) {
+        byte[] saltValue = createSaltValue(keyAlgoJwt, saltInput);
+        Digest digest = null;
+        int macSigSize = PBES_HMAC_MAP.get(keyAlgoJwt);
+        if (macSigSize == 256) { 
+            digest = new SHA256Digest();
+        } else if (macSigSize == 384) {
+            digest = new SHA384Digest();
+        } else {
+            digest = new SHA512Digest();
+        }
+        PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(digest);
+        gen.init(password, saltValue, pbesCount);
+        return ((KeyParameter) gen.generateDerivedParameters(keySize * 8)).getKey();
+    }
+    
+    
+    private static byte[] createSaltValue(String keyAlgoJwt, byte[] saltInput) {
+        byte[] algoBytes = stringToBytes(keyAlgoJwt);
+        byte[] saltValue = new byte[algoBytes.length + 1 + saltInput.length];
+        System.arraycopy(algoBytes, 0, saltValue, 0, algoBytes.length);
+        saltValue[algoBytes.length] = 0;
+        System.arraycopy(saltInput, 0, saltValue, algoBytes.length + 1, saltInput.length);
+        return saltValue;
+    }
+    static String validateKeyAlgorithm(String algo) {
+        if (!SUPPORTED_ALGORITHMS.contains(algo)) {
+            throw new SecurityException();
+        }
+        return algo;
+    }
+    static int validatePbesCount(int count) {
+        if (count < 1000) {
+            throw new SecurityException();
+        }
+        return count;
+    }    
+    
+    static byte[] stringToBytes(String str) {
+        try {
+            return str.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new SecurityException(ex);
+        }
+    }
+    static byte[] charsToBytes(char[] chars) {
+        ByteBuffer bb = Charset.forName("UTF-8").encode(CharBuffer.wrap(chars));
+        byte[] b = new byte[bb.remaining()];
+        bb.get(b);
+        return b;
+    }
+    @Override
+    public String getAlgorithm() {
+        return keyAlgoJwt;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyDecryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..a0ea63d
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyDecryptionAlgorithm.java
@@ -0,0 +1,45 @@
+/**
+ * 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.RSAPrivateKey;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+
+public class RSAOaepKeyDecryptionAlgorithm extends WrappedKeyDecryptionAlgorithm {
+    public RSAOaepKeyDecryptionAlgorithm(RSAPrivateKey privateKey) {    
+        this(privateKey, null);
+    }
+    public RSAOaepKeyDecryptionAlgorithm(RSAPrivateKey privateKey, String supportedAlgo) {    
+        this(privateKey, supportedAlgo, true);
+    }
+    public RSAOaepKeyDecryptionAlgorithm(RSAPrivateKey privateKey, String supportedAlgo, boolean unwrap) {    
+        super(privateKey, supportedAlgo, unwrap);
+    }
+    protected int getKeyCipherBlockSize() {
+        return ((RSAPrivateKey)getCekDecryptionKey()).getModulus().toByteArray().length;
+    }
+    @Override
+    protected void validateKeyEncryptionAlgorithm(String keyAlgo) {
+        super.validateKeyEncryptionAlgorithm(keyAlgo);
+        if (!Algorithm.isRsaOaep(keyAlgo)) {
+            throw new SecurityException();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyEncryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..b658e36
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAOaepKeyEncryptionAlgorithm.java
@@ -0,0 +1,39 @@
+/**
+ * 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.RSAPublicKey;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+
+public class RSAOaepKeyEncryptionAlgorithm extends AbstractWrapKeyEncryptionAlgorithm {
+    private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>(
+        Arrays.asList(Algorithm.RSA_OAEP.getJwtName(),
+                      Algorithm.RSA_OAEP_256.getJwtName()));
+    public RSAOaepKeyEncryptionAlgorithm(RSAPublicKey publicKey, String jweAlgo) {
+        this(publicKey, jweAlgo, true);
+    }
+    public RSAOaepKeyEncryptionAlgorithm(RSAPublicKey publicKey, String jweAlgo, boolean wrap) {
+        super(publicKey, jweAlgo, wrap, SUPPORTED_ALGORITHMS);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyDecryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..8af2c63
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyDecryptionAlgorithm.java
@@ -0,0 +1,85 @@
+/**
+ * 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;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.cxf.common.util.crypto.CryptoUtils;
+import org.apache.cxf.common.util.crypto.KeyProperties;
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+
+public class WrappedKeyDecryptionAlgorithm implements KeyDecryptionAlgorithm {
+    private Key cekDecryptionKey;
+    private boolean unwrap;
+    private String supportedAlgo;
+    public WrappedKeyDecryptionAlgorithm(Key cekDecryptionKey) {    
+        this(cekDecryptionKey, null);
+    }
+    public WrappedKeyDecryptionAlgorithm(Key cekDecryptionKey, String supportedAlgo) {    
+        this(cekDecryptionKey, supportedAlgo, true);
+    }
+    public WrappedKeyDecryptionAlgorithm(Key cekDecryptionKey, String supportedAlgo, boolean unwrap) {    
+        this.cekDecryptionKey = cekDecryptionKey;
+        this.supportedAlgo = supportedAlgo;
+        this.unwrap = unwrap;
+    }
+    public byte[] getDecryptedContentEncryptionKey(JweCompactConsumer consumer) {
+        KeyProperties keyProps = new KeyProperties(getKeyEncryptionAlgorithm(consumer));
+        AlgorithmParameterSpec spec = getAlgorithmParameterSpec(consumer); 
+        if (spec != null) {
+            keyProps.setAlgoSpec(spec);
+        }
+        if (!unwrap) {
+            keyProps.setBlockSize(getKeyCipherBlockSize());
+            return CryptoUtils.decryptBytes(getEncryptedContentEncryptionKey(consumer), 
+                                            getCekDecryptionKey(), keyProps);
+        } else {
+            return CryptoUtils.unwrapSecretKey(getEncryptedContentEncryptionKey(consumer), 
+                                               getContentEncryptionAlgorithm(consumer), 
+                                               getCekDecryptionKey(), 
+                                               keyProps).getEncoded();
+        }
+    }
+    
+    protected Key getCekDecryptionKey() {
+        return cekDecryptionKey;
+    }
+    protected int getKeyCipherBlockSize() {
+        return -1;
+    }
+    protected String getKeyEncryptionAlgorithm(JweCompactConsumer consumer) {
+        String keyAlgo = consumer.getJweHeaders().getKeyEncryptionAlgorithm();
+        return Algorithm.toJavaName(keyAlgo);
+    }
+    protected void validateKeyEncryptionAlgorithm(String keyAlgo) {
+        if (keyAlgo == null || supportedAlgo != null && supportedAlgo.equals(keyAlgo)) {
+            throw new SecurityException();
+        }
+    }
+    protected String getContentEncryptionAlgorithm(JweCompactConsumer consumer) {
+        return Algorithm.toJavaName(consumer.getJweHeaders().getContentEncryptionAlgorithm());
+    }
+    protected AlgorithmParameterSpec getAlgorithmParameterSpec(JweCompactConsumer consumer) {
+        return null;
+    }
+    protected byte[] getEncryptedContentEncryptionKey(JweCompactConsumer consumer) {
+        return consumer.getEncryptedContentEncryptionKey();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweDecryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweDecryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweDecryption.java
new file mode 100644
index 0000000..c74e880
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweDecryption.java
@@ -0,0 +1,34 @@
+/**
+ * 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 org.apache.cxf.rs.security.jose.JoseHeadersReader;
+
+public class WrappedKeyJweDecryption extends AbstractJweDecryption {
+    
+    public WrappedKeyJweDecryption(KeyDecryptionAlgorithm keyDecryptionAlgo,
+                                   ContentDecryptionAlgorithm contentDecryptionAlgo) {    
+        this(keyDecryptionAlgo, null, contentDecryptionAlgo);
+    }
+    public WrappedKeyJweDecryption(KeyDecryptionAlgorithm keyDecryptionAlgo,
+                                   JoseHeadersReader reader,
+                                   ContentDecryptionAlgorithm cipherProps) {    
+        super(reader, keyDecryptionAlgo, cipherProps);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweEncryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweEncryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweEncryption.java
new file mode 100644
index 0000000..446a675
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/WrappedKeyJweEncryption.java
@@ -0,0 +1,47 @@
+/**
+ * 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 org.apache.cxf.rs.security.jose.JoseHeadersWriter;
+
+public class WrappedKeyJweEncryption extends AbstractJweEncryption {
+    public WrappedKeyJweEncryption(KeyEncryptionAlgorithm keyEncryptionAlgorithm,
+                                   ContentEncryptionAlgorithm contentEncryptionAlgo) {
+        this(keyEncryptionAlgorithm, contentEncryptionAlgo, null);
+    }
+    public WrappedKeyJweEncryption(KeyEncryptionAlgorithm keyEncryptionAlgorithm,
+                                   ContentEncryptionAlgorithm contentEncryptionAlgo,
+                                   JoseHeadersWriter writer) {
+        this(new JweHeaders(keyEncryptionAlgorithm.getAlgorithm(), contentEncryptionAlgo.getAlgorithm()), 
+             keyEncryptionAlgorithm, contentEncryptionAlgo, writer);
+    }
+    public WrappedKeyJweEncryption(JweHeaders headers, 
+                                   KeyEncryptionAlgorithm keyEncryptionAlgorithm,
+                                   ContentEncryptionAlgorithm contentEncryptionAlgo) {
+        this(headers, keyEncryptionAlgorithm, contentEncryptionAlgo, null);
+    }
+    public WrappedKeyJweEncryption(JweHeaders headers, 
+                                   KeyEncryptionAlgorithm keyEncryptionAlgorithm,
+                                   ContentEncryptionAlgorithm contentEncryptionAlgo,
+                                   JoseHeadersWriter writer) {
+        super(headers, contentEncryptionAlgo, keyEncryptionAlgorithm, writer);
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/DefaultJwkReaderWriter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/DefaultJwkReaderWriter.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/DefaultJwkReaderWriter.java
new file mode 100644
index 0000000..fa4f8ba
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/DefaultJwkReaderWriter.java
@@ -0,0 +1,48 @@
+/**
+ * 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.jwk;
+
+import org.apache.cxf.rs.security.jose.AbstractJoseObjectReaderWriter;
+
+
+
+
+public class DefaultJwkReaderWriter extends AbstractJoseObjectReaderWriter
+    implements JwkReaderWriter {
+    @Override
+    public String jwkSetToJson(JsonWebKeys jwks) {
+        return toJson(jwks);
+    }
+    @Override
+    public JsonWebKeys jsonToJwkSet(String jwksJson) {
+        JsonWebKeys jwks = new JsonWebKeys();
+        fromJsonInternal(jwks, jwksJson);
+        return jwks;
+    }
+    @Override
+    public String jwkToJson(JsonWebKey jwk) {
+        return toJson(jwk);
+    }
+    @Override
+    public JsonWebKey jsonToJwk(String jwkJson) {
+        JsonWebKey jwk = new JsonWebKey();
+        fromJsonInternal(jwk, jwkJson);
+        return jwk;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/9c053334/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java
new file mode 100644
index 0000000..ef594e6
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java
@@ -0,0 +1,160 @@
+/**
+ * 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.jwk;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.rs.security.jose.AbstractJoseObject;
+import org.apache.cxf.rs.security.jose.JoseConstants;
+
+
+public class JsonWebKey extends AbstractJoseObject {
+    
+    public static final String KEY_TYPE = "kty";
+    public static final String PUBLIC_KEY_USE = "use";
+    public static final String KEY_OPERATIONS = "key_ops";
+    public static final String KEY_ALGO = JoseConstants.HEADER_ALGORITHM;
+    public static final String KEY_ID = JoseConstants.HEADER_KEY_ID;
+    public static final String X509_URL = JoseConstants.HEADER_X509_URL;
+    public static final String X509_CHAIN = JoseConstants.HEADER_X509_CHAIN;
+    public static final String X509_THUMBPRINT = JoseConstants.HEADER_X509_THUMBPRINT;
+    public static final String X509_THUMBPRINT_SHA256 = JoseConstants.HEADER_X509_THUMBPRINT_SHA256;
+    
+    public static final String KEY_TYPE_RSA = "RSA";
+    public static final String RSA_MODULUS = "n";
+    public static final String RSA_PUBLIC_EXP = "e";
+    public static final String RSA_PRIVATE_EXP = "d";
+    public static final String RSA_FIRST_PRIME_FACTOR = "p";
+    public static final String RSA_SECOND_PRIME_FACTOR = "q";
+    public static final String RSA_FIRST_PRIME_CRT = "dp";
+    public static final String RSA_SECOND_PRIME_CRT = "dq";
+    public static final String RSA_FIRST_CRT_COEFFICIENT = "qi";
+        
+    public static final String KEY_TYPE_OCTET = "oct";
+    public static final String OCTET_KEY_VALUE = "k";
+    
+    public static final String KEY_TYPE_ELLIPTIC = "EC";
+    public static final String EC_CURVE = "crv";
+    public static final String EC_CURVE_P256 = "P-256";
+    public static final String EC_CURVE_P384 = "P-384";
+    public static final String EC_CURVE_P512 = "P-512";
+    public static final String EC_X_COORDINATE = "x";
+    public static final String EC_Y_COORDINATE = "y";
+    public static final String EC_PRIVATE_KEY = "d";
+    
+    public static final String PUBLIC_KEY_USE_SIGN = "sig";
+    public static final String PUBLIC_KEY_USE_ENCRYPT = "enc";
+    
+    public static final String KEY_OPER_SIGN = "sign";
+    public static final String KEY_OPER_VERIFY = "verify";
+    public static final String KEY_OPER_ENCRYPT = "encrypt";
+    public static final String KEY_OPER_DECRYPT = "decrypt";
+    
+    public JsonWebKey() {
+        
+    }
+    
+    public JsonWebKey(Map<String, Object> values) {
+        super(values);
+    }
+    
+    public void setKeyType(String keyType) {
+        super.setValue(KEY_TYPE, keyType);
+    }
+
+    public String getKeyType() {
+        return (String)super.getValue(KEY_TYPE);
+    }
+
+    public void setPublicKeyUse(String use) {
+        super.setValue(PUBLIC_KEY_USE, use);
+    }
+    
+    public String getPublicKeyUse() {
+        return (String)super.getValue(PUBLIC_KEY_USE);
+    }
+
+    public void setKeyOperation(List<String> keyOperation) {
+        super.setValue(KEY_OPERATIONS, keyOperation);
+    }
+
+    public List<String> getKeyOperation() {
+        return CastUtils.cast((List<?>)super.getValue(KEY_OPERATIONS));
+    }
+    
+    public void setAlgorithm(String algorithm) {
+        super.setValue(KEY_ALGO, algorithm);
+    }
+
+    public String getAlgorithm() {
+        return (String)super.getValue(KEY_ALGO);
+    }
+    
+    public void setKid(String kid) {
+        super.setValue(KEY_ID, kid);
+    }
+
+    public String getKid() {
+        return (String)super.getValue(KEY_ID);
+    }
+    
+    public void setX509Url(String x509Url) {
+        super.setValue(X509_URL, x509Url);
+    }
+    
+    public String getX509Url() {
+        return (String)super.getValue(X509_URL);
+    }
+
+    public void setX509Chain(String x509Chain) {
+        super.setValue(X509_CHAIN, x509Chain);
+    }
+
+    public String getX509Chain() {
+        return (String)super.getValue(X509_CHAIN);
+    }
+    
+    public void setX509Thumbprint(String x509Thumbprint) {
+        super.setValue(X509_THUMBPRINT, x509Thumbprint);
+    }
+    
+    public String getX509Thumbprint() {
+        return (String)super.getValue(X509_THUMBPRINT);
+    }
+    
+    public void setX509ThumbprintSHA256(String x509Thumbprint) {
+        super.setValue(X509_THUMBPRINT_SHA256, x509Thumbprint);
+    }
+    
+    public String getX509ThumbprintSHA256() {
+        return (String)super.getValue(X509_THUMBPRINT_SHA256);
+    }
+    
+    public JsonWebKey setProperty(String name, Object value) {
+        super.setValue(name, value);
+        return this;
+    }
+    
+    public Object getProperty(String name) {
+        return super.getValue(name);
+    }
+    
+}