与其他许多人一样,我在维护系统时遇到加密问题。
进程A生成一些加密文本,稍后进程B必须解码。它们为此目的共享相同的代码,如下所示:
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);
}
}
}
这两个进程在不同的服务器上运行,包括Centos(进程A为5.3,进程B为6.4)
进程A没有明显的问题 - 要编码的字符串可靠地完成。
当流程B开始时,一切似乎都很好。它正确解码和解密所需的字符串。
然而,在大约24小时的某个时间点,这停止了工作。在这一点上,我得到了BadPaddingException"给定最后的块未正确填充"'例外。然后每次使用任何编码字符串执行代码时都会继续,直到重新启动进程为止,此时所有内容都会再次运行,包括解码之前失败的字符串。
当出现这种情况时,调用decrypt(encrypt(" test"))也会失败,所以这似乎与实际的加密值无关,更多的是与加密和解密相关一些如何不同步。
如果有人可以提出任何关于我可能出错的建议,我会很感激。
非常感谢...
安德鲁