View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2016 ForgeRock AS.
15   */
16  
17  package org.forgerock.json.jose.jwe.handlers.encryption;
18  
19  import java.security.GeneralSecurityException;
20  import java.security.Key;
21  
22  import javax.crypto.Cipher;
23  
24  import org.forgerock.json.jose.exceptions.JweDecryptionException;
25  import org.forgerock.json.jose.exceptions.JweEncryptionException;
26  import org.forgerock.json.jose.jwe.EncryptionMethod;
27  import org.forgerock.json.jose.jwe.JweEncryption;
28  
29  /**
30   * Provides JWE key encapsulation using the AES KeyWrap algorithm.
31   */
32  public final class AESKeyWrapEncryptionHandler implements EncryptionHandler {
33      private final ContentEncryptionHandler contentEncryptionHandler;
34      private final EncryptionMethod encryptionMethod;
35  
36      /**
37       * Constructs an AES KeyWrap encryption handler for the given underlying content encryption method.
38       *
39       * @param method the content encryption method.
40       */
41      public AESKeyWrapEncryptionHandler(final EncryptionMethod method) {
42          this.contentEncryptionHandler = ContentEncryptionHandler.getInstance(method);
43          this.encryptionMethod = method;
44      }
45  
46      @Override
47      public Key getContentEncryptionKey() {
48          return contentEncryptionHandler.generateEncryptionKey();
49      }
50  
51      @Override
52      public byte[] generateJWEEncryptedKey(final Key key, final Key contentEncryptionKey) {
53          try {
54              final Cipher cipher = Cipher.getInstance("AESWrap");
55              cipher.init(Cipher.WRAP_MODE, key);
56              return cipher.wrap(contentEncryptionKey);
57          } catch (GeneralSecurityException e) {
58              throw new JweEncryptionException(e);
59          }
60      }
61  
62      @Override
63      public byte[] generateInitialisationVector() {
64          return contentEncryptionHandler.generateInitialisationVector();
65      }
66  
67      @Override
68      public JweEncryption encryptPlaintext(final Key contentEncryptionKey, final byte[] initialisationVector,
69              final byte[] plaintext,
70              final byte[] additionalAuthenticatedData) {
71          return contentEncryptionHandler.encrypt(contentEncryptionKey, initialisationVector, plaintext,
72                  additionalAuthenticatedData);
73      }
74  
75      @Override
76      public Key decryptContentEncryptionKey(final Key key, final byte[] encryptedContentEncryptionKey) {
77          try {
78              final Cipher cipher = Cipher.getInstance("AESWrap");
79              cipher.init(Cipher.UNWRAP_MODE, key);
80              return cipher.unwrap(encryptedContentEncryptionKey, encryptionMethod.getEncryptionAlgorithm(),
81                      Cipher.SECRET_KEY);
82          } catch (GeneralSecurityException e) {
83              throw new JweDecryptionException();
84          }
85      }
86  
87      @Override
88      public byte[] decryptCiphertext(final Key contentEncryptionKey, final byte[] initialisationVector,
89              final byte[] ciphertext,
90              final byte[] authenticationTag, final byte[] additionalAuthenticatedData) {
91          return contentEncryptionHandler.decrypt(contentEncryptionKey, initialisationVector,
92                  new JweEncryption(ciphertext, authenticationTag), additionalAuthenticatedData);
93      }
94  }