Created
October 23, 2012 14:17
-
-
Save Robertof/3938993 to your computer and use it in GitHub Desktop.
[sharing time] Java AES256 CBC Helper Encryption/Decryption/Keygeneration/Serialization class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by Robertof <robertof.public@gmail.com / http://about.me/roberto.f>. | |
* File creation date: 10-ott-2012 19.12.25 | |
* Licensed under GNU/GPL v3. | |
*/ | |
package com.robertof; | |
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 java.util.ArrayList; | |
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.spec.IvParameterSpec; | |
import javax.crypto.spec.PBEKeySpec; | |
import javax.crypto.spec.SecretKeySpec; | |
public class EncManager { | |
private static final int IV_SIZE = (128 / 8); // 16 | |
private static final int SALT_SIZE = 8; | |
public static byte[] getSalt (int length) | |
{ | |
return new SecureRandom().generateSeed(length); | |
} | |
public static byte[] getSalt() | |
{ | |
return getSalt(SALT_SIZE); | |
} | |
public static SecretKey getKey (char[] password, byte[] salt) | |
throws NoSuchAlgorithmException, InvalidKeySpecException | |
{ | |
if (password == null) return null; | |
if (salt == null) return null; | |
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); | |
KeySpec spec = new PBEKeySpec (password, salt, 65536, 128); | |
SecretKey tmp = factory.generateSecret(spec); | |
return new SecretKeySpec (tmp.getEncoded(), "AES"); | |
} | |
public static ArrayList<byte[]> encrypt (String str, SecretKey key) | |
throws NoSuchAlgorithmException, NoSuchPaddingException, | |
InvalidKeyException, InvalidParameterSpecException, | |
IllegalBlockSizeException, UnsupportedEncodingException, | |
BadPaddingException, CryptographicException | |
{ | |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipher.init(Cipher.ENCRYPT_MODE, key); | |
AlgorithmParameters params = cipher.getParameters(); | |
ArrayList<byte[]> list = new ArrayList<byte[]>(); | |
list.add(params.getParameterSpec(IvParameterSpec.class).getIV()); | |
if (list.get(0).length != IV_SIZE) | |
throw new CryptographicException ("Incorrect IV size"); | |
list.add(cipher.doFinal(str.getBytes("UTF-8"))); | |
return list; | |
} | |
public static ArrayList<byte[]> encrypt (byte[] bytes, SecretKey key) | |
throws NoSuchAlgorithmException, NoSuchPaddingException, | |
InvalidKeyException, InvalidParameterSpecException, | |
IllegalBlockSizeException, UnsupportedEncodingException, | |
BadPaddingException, CryptographicException | |
{ | |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipher.init(Cipher.ENCRYPT_MODE, key); | |
AlgorithmParameters params = cipher.getParameters(); | |
ArrayList<byte[]> list = new ArrayList<byte[]>(); | |
list.add(params.getParameterSpec(IvParameterSpec.class).getIV()); | |
if (list.get(0).length != IV_SIZE) | |
throw new CryptographicException ("Incorrect IV size"); | |
list.add(cipher.doFinal(bytes)); | |
return list; | |
} | |
public static String decrypt (byte[] encrypted, SecretKey key, byte[] iv) | |
throws NoSuchAlgorithmException, NoSuchPaddingException, | |
InvalidKeyException, InvalidAlgorithmParameterException, | |
IllegalBlockSizeException, UnsupportedEncodingException, | |
BadPaddingException | |
{ | |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipher.init (Cipher.DECRYPT_MODE, key, new IvParameterSpec (iv)); | |
return new String (cipher.doFinal(encrypted), "UTF-8"); | |
} | |
public static byte[] decryptByte (byte[] encrypted, SecretKey key, byte[] iv) | |
throws NoSuchAlgorithmException, NoSuchPaddingException, | |
InvalidKeyException, InvalidAlgorithmParameterException, | |
IllegalBlockSizeException, UnsupportedEncodingException, | |
BadPaddingException | |
{ | |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipher.init (Cipher.DECRYPT_MODE, key, new IvParameterSpec (iv)); | |
return cipher.doFinal(encrypted); | |
} | |
public static String serializeData (ArrayList<byte[]> encrypted, byte[] salt) | |
{ | |
byte[] iv = encrypted.get(0); | |
byte[] ciphertext = encrypted.get(1); | |
return "__SALTED" + Utils.bytesToHex(salt) + Utils.bytesToHex(iv) + Utils.bytesToHex(ciphertext); | |
} | |
public static ArrayList<byte[]> unserializeData (String mixedData) | |
throws CryptographicException | |
{ | |
// get header which should be __SALTED | |
int _len = 8; | |
if (!mixedData.substring(0, _len).equalsIgnoreCase("__SALTED")) | |
throw new CryptographicException ("Invalid header."); | |
// get salt | |
String salt = mixedData.substring(_len, _len + (SALT_SIZE * 2)); | |
_len += SALT_SIZE * 2; | |
// parse the bytes | |
byte[] rSalt = Utils.hexToBytes(salt); | |
if (rSalt.length != SALT_SIZE) | |
throw new CryptographicException ("Invalid salt."); | |
// get IV | |
String IVs = mixedData.substring(_len, _len + (IV_SIZE * 2)); | |
_len += IV_SIZE * 2; | |
// parse IV | |
byte[] IV = Utils.hexToBytes(IVs); | |
if (IV.length != IV_SIZE) | |
throw new CryptographicException ("Invalid IV."); | |
// get ciphertext | |
String cTextH = mixedData.substring(_len); | |
byte[] cText = Utils.hexToBytes(cTextH); | |
// prepare and return final arraylist | |
ArrayList<byte[]> alist = new ArrayList<byte[]>(); | |
alist.add(rSalt); alist.add(IV); alist.add(cText); | |
return alist; | |
} | |
public static byte[] serializedGetSalt (ArrayList<byte[]> unserialized) | |
{ | |
return unserialized.get(0); | |
} | |
public static byte[] serializedGetIV (ArrayList<byte[]> unserialized) | |
{ | |
return unserialized.get(1); | |
} | |
public static byte[] serializedGetCipherText (ArrayList<byte[]> unserialized) | |
{ | |
return unserialized.get(2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment