Reputation: 115
I am new java to encryption. Trying to implement something light weight to encrypt a string and store it somewhere and de-crypt it back before using.
With some web search I came up with this for encryption and decryption.
public static String base64Encode(byte[] bytes)
{
return new BASE64Encoder().encode(bytes);
}
public static byte[] base64Decode(String property) throws IOException
{
return new BASE64Decoder().decodeBuffer(property);
}
public static String encrypt(String mystring) throws GeneralSecurityException, UnsupportedEncodingException
{
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(mystring.toCharArray()));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
return base64Encode(pbeCipher.doFinal(mystring.getBytes("UTF-8")));
}
public static String decrypt(String estring) throws GeneralSecurityException, IOException
{
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(estring.toCharArray()));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
return new String(pbeCipher.doFinal(base64Decode(estring)), "UTF-8");
}
I see that encryption worked but I saw a padding related exception in the decryption part, from the doFinal block. Here it is...
encrypted string:zdrtgOKfkZMgpCOflr1ILQ== -> Encrypted String
exceptionjavax.crypto.BadPaddingException: Given
final block not properly padded -> Exception from the doFinal block.
Seems like when I encrypted it, I need to do some kind of padding.
Can any one tell me what went wrong and how can it be fixed?
Thanks
Tas
Upvotes: 0
Views: 374
Reputation: 338
Change your code ,
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(mystring.toCharArray()));
to
SecretKey key = keyFactory.generateSecret(new PBEKeySpec("PASSWORD".toCharArray(), SALT, 20));
Upvotes: 0
Reputation: 19435
You are using password based encryption here. This means that the encryption key itself is based upon a password. You must use the same password for both encryption and decryption.
private static char[] ENCRYPTION_PASSWORD
= "some password populated by configuration".toCharArray();
public static String encrypt(String mystring)
throws GeneralSecurityException, UnsupportedEncodingException {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(ENCRYPTION_PASSWORD));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
return DatatypeConverter
.printBase64Binary(pbeCipher.doFinal(mystring.getBytes("UTF-8")));
}
public static String decrypt(String string)
throws GeneralSecurityException, IOException {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(ENCRYPTION_PASSWORD));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
return new String(pbeCipher.doFinal(DatatypeConverter
.parseBase64Binary(estring)), "UTF-8");
}
Note also the use of javax.xml.bind.DatatypeConverter for base64 operations. No need to write your own or use third parties these days.
Upvotes: 1
Reputation: 6711
You will need to first decode your input to the decrypt method.
Call the base64Decode
method and the estring
parameter in your decrypt
method.
That should do it.
Upvotes: 0