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 2013-2016 ForgeRock AS.
15   */
16  
17  package org.forgerock.json.jose.jwe.handlers.encryption;
18  
19  import java.security.GeneralSecurityException;
20  import java.security.InvalidAlgorithmParameterException;
21  import java.security.InvalidKeyException;
22  import java.security.Key;
23  import java.security.NoSuchAlgorithmException;
24  import java.util.logging.Level;
25  import java.util.logging.Logger;
26  
27  import javax.crypto.BadPaddingException;
28  import javax.crypto.Cipher;
29  import javax.crypto.IllegalBlockSizeException;
30  import javax.crypto.NoSuchPaddingException;
31  import javax.crypto.spec.IvParameterSpec;
32  import javax.crypto.spec.SecretKeySpec;
33  
34  import org.forgerock.json.jose.exceptions.JweDecryptionException;
35  import org.forgerock.json.jose.exceptions.JweEncryptionException;
36  
37  /**
38   * A base implementation of an EncryptionHandler that provides common encryption and decryption methods for all
39   * concrete EncryptionHandler implementations.
40   *
41   * @since 2.0.0
42   * @deprecated Use {@link ContentEncryptionHandler} instead.
43   */
44  @Deprecated
45  public abstract class AbstractEncryptionHandler implements EncryptionHandler {
46      private static final Logger LOGGER = Logger.getLogger(AbstractEncryptionHandler.class.getName());
47  
48      /**
49       * Encrypts the given plaintext using the specified key with the specified encryption algorithm.
50       *
51       * @param algorithm The Java Cryptographic encryption algorithm.
52       * @param key The encryption key.
53       * @param data The data to encrypt.
54       * @return An array of bytes representing the encrypted data.
55       */
56      protected byte[] encrypt(String algorithm, Key key, byte[] data) {
57          try {
58              Cipher cipher = Cipher.getInstance(algorithm);
59              cipher.init(Cipher.ENCRYPT_MODE, key);
60              return cipher.doFinal(data);
61          } catch (NoSuchAlgorithmException e) {
62              throw new JweEncryptionException("Unsupported Encryption Algorithm, " + algorithm, e);
63          } catch (IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | BadPaddingException e) {
64              throw new JweEncryptionException(e);
65          }
66      }
67  
68      /**
69       * Encrypts the given plaintext using the specified key and initialisation vector with the specified encryption
70       * algorithm.
71       *
72       * @param algorithm The Java Cryptographic encryption algorithm.
73       * @param key The encryption key.
74       * @param initialisationVector The initialisation vector.
75       * @param data The data to encrypt.
76       * @return An array of bytes representing the encrypted data.
77       */
78      protected byte[] encrypt(String algorithm, Key key, byte[] initialisationVector, byte[] data) {
79  
80          try {
81              Cipher cipher = Cipher.getInstance(algorithm);
82              SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), key.getAlgorithm());
83              IvParameterSpec ivParameterSpec = new IvParameterSpec(initialisationVector);
84              cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
85              return cipher.doFinal(data);
86          } catch (NoSuchAlgorithmException e) {
87              throw new JweEncryptionException("Unsupported Encryption Algorithm, " + algorithm, e);
88          } catch (IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | BadPaddingException
89                  | InvalidAlgorithmParameterException e) {
90              throw new JweEncryptionException(e);
91          }
92      }
93  
94      /**
95       * Decrypts the given ciphertext using the private key and with the same encryption algorithm that was used in the
96       * encryption.
97       *
98       * @param algorithm The Java Cryptographic encryption algorithm.
99       * @param privateKey The private key pair to the public key used in the encryption.
100      * @param data The ciphertext to decrypt.
101      * @return An array of bytes representing the decrypted data.
102      */
103     public byte[] decrypt(String algorithm, Key privateKey, byte[] data) {
104 
105         try {
106             Cipher cipher = Cipher.getInstance(algorithm);
107             cipher.init(Cipher.DECRYPT_MODE, privateKey);
108             return cipher.doFinal(data);
109         } catch (GeneralSecurityException e) {
110             logDecryptionFailure(e);
111             throw new JweDecryptionException();
112         }
113     }
114 
115     /**
116      * Decrypts the given ciphertext using the private key and initialisation vector with the same encryption algorithm
117      * that was used in the encryption.
118      *
119      * @param algorithm The Java Cryptographic encryption algorithm.
120      * @param key The private key pair to the public key used in the encryption.
121      * @param initialisationVector The same initialisation vector that was used in the encryption.
122      * @param data The ciphertext to decrypt.
123      * @return An array of bytes representing the decrypted data.
124      */
125     protected byte[] decrypt(String algorithm, Key key, byte[] initialisationVector, byte[] data) {
126 
127         try {
128             Cipher cipher = Cipher.getInstance(algorithm);
129             SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), key.getAlgorithm());
130             IvParameterSpec ivParameterSpec = new IvParameterSpec(initialisationVector);
131             cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
132             return cipher.doFinal(data);
133         } catch (GeneralSecurityException e) {
134             logDecryptionFailure(e);
135             throw new JweDecryptionException();
136         }
137     }
138 
139     /**
140      * Log the root cause of any decryption error before throwing a generic exception.
141      */
142     private void logDecryptionFailure(Throwable cause) {
143         if (LOGGER.isLoggable(Level.FINE)) {
144             LOGGER.log(Level.FINE, "Decryption failed: " + cause, cause);
145         }
146     }
147 }