001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2013-2015 ForgeRock AS. 015 */ 016 017package org.forgerock.json.jose.jwe.handlers.encryption; 018 019import java.security.GeneralSecurityException; 020import java.security.InvalidAlgorithmParameterException; 021import java.security.InvalidKeyException; 022import java.security.Key; 023import java.security.NoSuchAlgorithmException; 024import java.util.logging.Level; 025import java.util.logging.Logger; 026 027import javax.crypto.BadPaddingException; 028import javax.crypto.Cipher; 029import javax.crypto.IllegalBlockSizeException; 030import javax.crypto.NoSuchPaddingException; 031import javax.crypto.spec.IvParameterSpec; 032import javax.crypto.spec.SecretKeySpec; 033 034import org.forgerock.json.jose.exceptions.JweDecryptionException; 035import org.forgerock.json.jose.exceptions.JweEncryptionException; 036 037/** 038 * A base implementation of an EncryptionHandler that provides common encryption and decryption methods for all 039 * concrete EncryptionHandler implementations. 040 * 041 * @since 2.0.0 042 */ 043public abstract class AbstractEncryptionHandler implements EncryptionHandler { 044 private static final Logger LOGGER = Logger.getLogger(AbstractEncryptionHandler.class.getName()); 045 046 /** 047 * Encrypts the given plaintext using the specified key with the specified encryption algorithm. 048 * 049 * @param algorithm The Java Cryptographic encryption algorithm. 050 * @param key The encryption key. 051 * @param data The data to encrypt. 052 * @return An array of bytes representing the encrypted data. 053 */ 054 protected byte[] encrypt(String algorithm, Key key, byte[] data) { 055 try { 056 Cipher cipher = Cipher.getInstance(algorithm); 057 cipher.init(Cipher.ENCRYPT_MODE, key); 058 return cipher.doFinal(data); 059 } catch (NoSuchAlgorithmException e) { 060 throw new JweEncryptionException("Unsupported Encryption Algorithm, " + algorithm, e); 061 } catch (IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | BadPaddingException e) { 062 throw new JweEncryptionException(e); 063 } 064 } 065 066 /** 067 * Encrypts the given plaintext using the specified key and initialisation vector with the specified encryption 068 * algorithm. 069 * 070 * @param algorithm The Java Cryptographic encryption algorithm. 071 * @param key The encryption key. 072 * @param initialisationVector The initialisation vector. 073 * @param data The data to encrypt. 074 * @return An array of bytes representing the encrypted data. 075 */ 076 protected byte[] encrypt(String algorithm, Key key, byte[] initialisationVector, byte[] data) { 077 078 try { 079 Cipher cipher = Cipher.getInstance(algorithm); 080 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), key.getAlgorithm()); 081 IvParameterSpec ivParameterSpec = new IvParameterSpec(initialisationVector); 082 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); 083 return cipher.doFinal(data); 084 } catch (NoSuchAlgorithmException e) { 085 throw new JweEncryptionException("Unsupported Encryption Algorithm, " + algorithm, e); 086 } catch (IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | BadPaddingException 087 | InvalidAlgorithmParameterException e) { 088 throw new JweEncryptionException(e); 089 } 090 } 091 092 /** 093 * Decrypts the given ciphertext using the private key and with the same encryption algorithm that was used in the 094 * encryption. 095 * 096 * @param algorithm The Java Cryptographic encryption algorithm. 097 * @param privateKey The private key pair to the public key used in the encryption. 098 * @param data The ciphertext to decrypt. 099 * @return An array of bytes representing the decrypted data. 100 */ 101 public byte[] decrypt(String algorithm, Key privateKey, byte[] data) { 102 103 try { 104 Cipher cipher = Cipher.getInstance(algorithm); 105 cipher.init(Cipher.DECRYPT_MODE, privateKey); 106 return cipher.doFinal(data); 107 } catch (GeneralSecurityException e) { 108 logDecryptionFailure(e); 109 throw new JweDecryptionException(); 110 } 111 } 112 113 /** 114 * Decrypts the given ciphertext using the private key and initialisation vector with the same encryption algorithm 115 * that was used in the encryption. 116 * 117 * @param algorithm The Java Cryptographic encryption algorithm. 118 * @param key The private key pair to the public key used in the encryption. 119 * @param initialisationVector The same initialisation vector that was used in the encryption. 120 * @param data The ciphertext to decrypt. 121 * @return An array of bytes representing the decrypted data. 122 */ 123 protected byte[] decrypt(String algorithm, Key key, byte[] initialisationVector, byte[] data) { 124 125 try { 126 Cipher cipher = Cipher.getInstance(algorithm); 127 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), key.getAlgorithm()); 128 IvParameterSpec ivParameterSpec = new IvParameterSpec(initialisationVector); 129 cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); 130 return cipher.doFinal(data); 131 } catch (GeneralSecurityException e) { 132 logDecryptionFailure(e); 133 throw new JweDecryptionException(); 134 } 135 } 136 137 /** 138 * Log the root cause of any decryption error before throwing a generic exception. 139 */ 140 private void logDecryptionFailure(Throwable cause) { 141 if (LOGGER.isLoggable(Level.FINE)) { 142 LOGGER.log(Level.FINE, "Decryption failed: " + cause, cause); 143 } 144 } 145}