Skip to content

Instantly share code, notes, and snippets.

@Robertof
Created October 23, 2012 14:17
Show Gist options
  • Save Robertof/3938993 to your computer and use it in GitHub Desktop.
Save Robertof/3938993 to your computer and use it in GitHub Desktop.
[sharing time] Java AES256 CBC Helper Encryption/Decryption/Keygeneration/Serialization class
/**
* 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