Java tutorial
/* * alfcrypto is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * alfcrypto 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */ package com.fegor.alfresco.security.crypto; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidParameterSpecException; import java.security.spec.KeySpec; import org.apache.log4j.Logger; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; public class Crypto { private final Logger logger = Logger.getLogger(Crypto.class); String password = null; public final static int SALT_LEN = 8; byte[] vector_init = null; byte[] salt_pos = null; byte[] input; byte[] output; Cipher eCipher = null; Cipher deCipher = null; private final int KEYLEN_BITS = 128; private final int ITERATIONS = 65536; /** * Constructor */ public Crypto() { } /** * Encryption configuration * * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidParameterSpecException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws UnsupportedEncodingException * @throws InvalidKeyException */ public void configEncrypt() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidKeyException { SecretKeyFactory factory = null; SecretKey tmp = null; salt_pos = new byte[SALT_LEN]; SecureRandom rnd = new SecureRandom(); rnd.nextBytes(salt_pos); if (logger.isDebugEnabled()) logger.debug(this.getClass().getName() + ": [salt: " + (new String(Hex.encodeHex(salt_pos))) + "]"); factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); /* * http://www.javamex.com/tutorials/cryptography/unrestricted_policy_files * .shtml */ KeySpec spec = new PBEKeySpec(password.toCharArray(), salt_pos, ITERATIONS, KEYLEN_BITS); tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); eCipher.init(Cipher.ENCRYPT_MODE, secret); AlgorithmParameters params = eCipher.getParameters(); vector_init = params.getParameterSpec(IvParameterSpec.class).getIV(); if (logger.isDebugEnabled()) logger.debug( this.getClass().getName() + ": [vector ini: " + (new String(Hex.encodeHex(vector_init))) + "]"); } /** * Decryption configuration * * @param initvec * @param salt * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws InvalidAlgorithmParameterException * @throws DecoderException */ public void configDecrypt(String initvec, String salt) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, DecoderException { SecretKeyFactory factory = null; SecretKey tmp = null; SecretKey secret = null; salt_pos = Hex.decodeHex(salt.toCharArray()); if (logger.isDebugEnabled()) logger.debug(this.getClass().getName() + ": [salt: " + (new String(Hex.encodeHex(salt_pos))) + "]"); vector_init = Hex.decodeHex(initvec.toCharArray()); if (logger.isDebugEnabled()) logger.debug( this.getClass().getName() + ": [vector ini: " + (new String(Hex.encodeHex(vector_init))) + "]"); /* * http://www.javamex.com/tutorials/cryptography/unrestricted_policy_files * .shtml */ factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec spec = new PBEKeySpec(password.toCharArray(), salt_pos, ITERATIONS, KEYLEN_BITS); tmp = factory.generateSecret(spec); secret = new SecretKeySpec(tmp.getEncoded(), "AES"); deCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); deCipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(vector_init)); } /** * Cipher input * * @param input * - the cleartext file to be encrypted * @param output * - the encrypted data file * @throws IOException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws ShortBufferException */ public void Cipher() throws IOException, IllegalBlockSizeException, BadPaddingException, ShortBufferException { try { this.output = eCipher.doFinal(this.input); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } } /** * Decipher input * * @param input * - the cleartext file to be encrypted * @param output * - the encrypted data file * @throws IOException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws ShortBufferException */ public void Decipher() throws IOException, IllegalBlockSizeException, BadPaddingException, ShortBufferException { try { this.output = deCipher.doFinal(this.input); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } } /* * Methods setter and getter */ public void setInput(byte[] input) { this.input = input; } public void setPassword(String password) { this.password = password; } public String getSalt() { return (new String(Hex.encodeHex(salt_pos))); } public String getVectorInit() { return (new String(Hex.encodeHex(vector_init))); } public byte[] getOutput() { return this.output; } }