Java tutorial
/* * org.toffi * * File Name: AESEncryptorImpl.java * * Copyright 2014 Dzhem Riza * * Licensed 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.toffi.domainmodel.encryptor.impl; import org.apache.commons.codec.digest.DigestUtils; import org.apache.log4j.Logger; import org.toffi.domainmodel.encryptor.Encryptor; import org.toffi.domainmodel.encryptor.exceptions.EncryptorException; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; /** * Password based encryption using AES. */ public class AESEncryptorImpl implements Encryptor { private final Logger LOG = Logger.getLogger(AESEncryptorImpl.class); private final SecretKeySpec key; private final SecureRandom random; private final Cipher encCipher; private final Cipher decCipher; private final int ivLen; /** * Initializes encryptor with current encryption key. * * @param password */ public AESEncryptorImpl(String password) { try { // key = new SecretKeySpec(DigestUtils.sha256(password), "AES"); key = new SecretKeySpec(DigestUtils.sha256(password), 0, 16, Constants.AES); // initialize secure random random = SecureRandom.getInstance(Constants.SHA1PRNG); // initialize ciphers encCipher = Cipher.getInstance(Constants.AES_MODE); decCipher = Cipher.getInstance(Constants.AES_MODE); ivLen = encCipher.getBlockSize(); } catch (Exception e) { throw new EncryptorException("Error while initializing AESEncryptorImpl.", e); } } @Override public byte[] encrypt(byte[] data) { try { // generate random initialization vector byte[] iv = new byte[ivLen]; synchronized (random) { random.nextBytes(iv); } // encrypt IvParameterSpec paramSpec = new IvParameterSpec(iv); byte[] encryptedMessage = null; synchronized (encCipher) { encCipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); encryptedMessage = encCipher.doFinal(data); } // finalMessage = iv + encryptedMessage byte[] finalMessage = new byte[encryptedMessage.length + ivLen]; System.arraycopy(iv, 0, finalMessage, 0, ivLen); System.arraycopy(encryptedMessage, 0, finalMessage, ivLen, encryptedMessage.length); return finalMessage; } catch (Exception e) { LOG.error("Unable to decrypt input message", e); throw new EncryptorException("Encryption error!", e); } } @Override public byte[] decrypt(byte[] data) { try { // split message in iv - cipheredMessage int cipheredMessageLen = data.length - ivLen; byte[] iv = new byte[ivLen]; byte[] cipheredMessage = new byte[cipheredMessageLen]; System.arraycopy(data, 0, iv, 0, ivLen); System.arraycopy(data, ivLen, cipheredMessage, 0, cipheredMessageLen); // decrypt byte[] decryptedMessage = null; IvParameterSpec paramSpec = new IvParameterSpec(iv); synchronized (decCipher) { decCipher.init(Cipher.DECRYPT_MODE, key, paramSpec); decryptedMessage = decCipher.doFinal(cipheredMessage); } return decryptedMessage; } catch (Exception e) { LOG.error("Unable to decrypt input message", e); throw new EncryptorException("Decryption error!", e); } } }