Like many others over time I'm having issues with encryption in a system I'm maintaining.
Process A generates some encrypted text which later Process B must decode. They share the same code for this purpose which is as below:
public class DesEncryption {
private Cipher mEcipher;
private Cipher mDcipher;
private byte[] salt = {
(byte) 0x08, (byte) 0x90, (byte) 0xA6, (byte) 0x4B,
(byte) 0xBB, (byte) 0x51, (byte) 0x3C, (byte) 0xDE
};
// Iteration count
int iterationCount = 19;
DesEncryption(String passPhrase) throws EncryptionException {
try {
// Create the key
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance(
"PBEWithMD5AndDES").generateSecret(keySpec);
mEcipher = Cipher.getInstance(key.getAlgorithm());
mDcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameter to the ciphers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
// Create the ciphers
mEcipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
mDcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (java.security.InvalidAlgorithmParameterException e) {
throw new EncryptionException(e);
} catch (java.security.spec.InvalidKeySpecException e) {
throw new EncryptionException(e);
} catch (javax.crypto.NoSuchPaddingException e) {
throw new EncryptionException(e);
} catch (java.security.NoSuchAlgorithmException e) {
throw new EncryptionException(e);
} catch (java.security.InvalidKeyException e) {
throw new EncryptionException(e);
}
}
public String encrypt(String str) throws EncryptionException {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = mEcipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
} catch (javax.crypto.BadPaddingException e) {
throw new EncryptionException(e);
} catch (IllegalBlockSizeException e) {
throw new EncryptionException(e);
} catch (UnsupportedEncodingException e) {
throw new EncryptionException(e);
} catch (java.io.IOException e) {
throw new EncryptionException(e);
}
}
public String decrypt(String str) throws EncryptionException {
try {
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
// Decrypt
byte[] utf8 = mDcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (javax.crypto.BadPaddingException e) {
throw new EncryptionException(e);
} catch (IllegalBlockSizeException e) {
throw new EncryptionException(e);
} catch (UnsupportedEncodingException e) {
throw new EncryptionException(e);
} catch (java.io.IOException e) {
throw new EncryptionException(e);
}
}
}
The two processes run on separate servers, both Centos (5.3 for process A, 6.4 for Process B)
There are no apparent issues with Process A - The string to be encoded is done so reliably.
When process B starts, everything appears to be fine. It decodes and decrypts the required strings correctly.
At some point over the course of about 24 hours however, this stops working. At this point, I get the 'BadPaddingException "Given final block not properly padded"' Exceptions. This then continues every time the code is executed with any encoded string until such time as the process is restarted, at which point everything works again, including decoding strings that failed moments before.
At the time when this goes wrong, calling decrypt(encrypt("test")) will fail too so this seems to be unrelated to the actual encrypted value and more to do with the encryption and decryption getting out of sync some how.
If anyone could offer any suggestions about where I may be going wrong with this I'd appreciate it.
Many thanks in advance...
Andrew