/* * Universal Password Manager * Copyright (C) 2005-2013 Adrian Smith * * This file is part of Universal Password Manager. * * Universal Password Manager is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Universal Password Manager is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Universal Password Manager; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com._17od.upm.crypto; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; public class EncryptionService { private static final String randomAlgorithm = "SHA1PRNG"; public static final int SALT_LENGTH = 8; private byte[] salt; private BufferedBlockCipher encryptCipher; private BufferedBlockCipher decryptCipher; public EncryptionService(char[] password) throws CryptoException { try { this.salt = generateSalt(); } catch (NoSuchAlgorithmException e) { throw new CryptoException(e); } initCipher(password); } public EncryptionService(char[] password, byte[] salt) { this.salt = salt; initCipher(password); } public void initCipher(char[] password) { PBEParametersGenerator keyGenerator = new PKCS12ParametersGenerator(new SHA256Digest()); keyGenerator.init(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password), salt, 20); CipherParameters keyParams = keyGenerator.generateDerivedParameters(256, 128); encryptCipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding()); encryptCipher.init(true, keyParams); decryptCipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding()); decryptCipher.init(false, keyParams); } private byte[] generateSalt() throws NoSuchAlgorithmException { SecureRandom saltGen = SecureRandom.getInstance(randomAlgorithm); byte pSalt[] = new byte[SALT_LENGTH]; saltGen.nextBytes(pSalt); return pSalt; } public byte[] encrypt(byte[] plainText) throws CryptoException { byte[] encryptedBytes = new byte[encryptCipher.getOutputSize(plainText.length)]; int outputLength = encryptCipher.processBytes(plainText, 0, plainText.length, encryptedBytes, 0); try { outputLength += encryptCipher.doFinal(encryptedBytes, outputLength); } catch (InvalidCipherTextException e) { throw new CryptoException(e); } byte[] results = new byte[outputLength]; System.arraycopy(encryptedBytes, 0, results, 0, outputLength); return results; } public byte[] decrypt(byte[] encryptedBytes) throws CryptoException { byte[] decryptedBytes = new byte[decryptCipher.getOutputSize(encryptedBytes.length)]; int outputLength = decryptCipher.processBytes(encryptedBytes, 0, encryptedBytes.length, decryptedBytes, 0); try { outputLength += decryptCipher.doFinal(decryptedBytes, outputLength); } catch (InvalidCipherTextException e) { throw new CryptoException(e); } byte[] results = new byte[outputLength]; System.arraycopy(decryptedBytes, 0, results, 0, outputLength); return results; } public byte[] getSalt() { return salt; } }