In my application i want to store some secure data by encrypting it. When the user wants i need to show it to him by decrypting it.
This is working fine.
But the problem is i need to store both encrypted message and initialization vector for every message. This initialization vector is generated while encrypting and i have to use this while decrypting to get the original message.
So if the user stores 1000 messages i need to store those 1000 encrypted messages and corresponding 1000 initialization vectors.I want to avoid storing initialization vector for every message.
Please tell me the way to AES-256 encryption with out Initialization vector.
Below is my code for encrypting and decrypting
/*
* This method will do the AES-256 encryption.
*/
private byte[] encrypt(char[] raw, String cardno) {
// This raw is some unique key like password.
SecretKeyFactory factory = null;
SecretKey tmp = null;
Cipher cipher = null;
byte[] ciphertext = null;
AlgorithmParameters params = null;
try {
factory = SecretKeyFactory.getInstance("PBEWITHSHA-256AND256BITAES-CBC-BC");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
KeySpec spec = new PBEKeySpec(raw, mSalt, 1024, 256);
try {
if (factory != null)
tmp = factory.generateSecret(spec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
if (tmp != null)
mSecret = new SecretKeySpec(tmp.getEncoded(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
try {
if (cipher != null)
cipher.init(Cipher.ENCRYPT_MODE, mSecret);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
if (cipher != null)
params = cipher.getParameters();
try {
mIV = params.getParameterSpec(IvParameterSpec.class).getIV();
} catch (InvalidParameterSpecException e) {
e.printStackTrace();
}
try {
ciphertext = cipher.doFinal(cardno.getBytes("UTF-8"));
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return ciphertext;
}
/*
* This will decrypt the encrypted data based on provided key
*/
private byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
//This raw is initialization vector generated while encrypting
Cipher cipher = null;
byte[] decrypted = null;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
try {
cipher.init(Cipher.DECRYPT_MODE, mSecret, new IvParameterSpec(raw));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
try {
decrypted = cipher.doFinal(encrypted);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return decrypted;
}
To be secure, you must use an initialization vector (and a unique one) for each message. There is no way to get around it.