我正在使用Blowfish实现一个简单的密码存储。一切都很好,直到我尝试了几个不同的密码/密钥组合,并遇到了许多解密值仍然是垃圾的实例。
以下是演示此问题的独立类。我得到以下输出:
'Aaaaaaa7' encrypted: 'r?—èLèdÓ,·Ã¸ÍÒ'*
'Aaaaaaa7' decrypted: 'ñü=€¼(T'*
知道我需要做些什么才能保证它始终正确解密。
(在JDK 1.6.0_26中使用jce.jar)
谢谢,
大卫
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class BlowfishTwoWayHashImpl {
static {
test();
}
public static void test() {
String key = "wibble";
String passwordToEnrypt = "Aaaaaaa7";
String enc = BlowfishTwoWayHashImpl.encryptBlowfish(passwordToEnrypt, key);
System.out.println("'" + passwordToEnrypt + "' encrypted: '" + enc + "'");
String dec = BlowfishTwoWayHashImpl.decryptBlowfish(enc, key);
System.out.println("'" + passwordToEnrypt + "' decrypted: '" + dec + "'");
}
private static final String CIPHER_NAME = "Blowfish";
public static String encryptBlowfish(String toEncrypt, String key) {
return processString(toEncrypt, key, Cipher.ENCRYPT_MODE);
}
public static String decryptBlowfish(String toDecrypt, String key) {
return processString(toDecrypt, key, Cipher.DECRYPT_MODE);
}
private static String processString(String toEncrypt, String key, int encryptDecryptMode) {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), CIPHER_NAME);
Cipher cipher;
try {
cipher = Cipher.getInstance(CIPHER_NAME);
cipher.init(encryptDecryptMode, secretKeySpec);
return new String(cipher.doFinal(toEncrypt.getBytes()));
}
catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
}
答案 0 :(得分:4)
不要这样做:
return new String(cipher.doFinal(toEncrypt.getBytes()));
您在代码中使用的是平台默认编码。 不要这样做。它会丢失数据。
当您将正版文本转换为字节(例如加密时)时,请使用特定的字符集 - UTF-8是一个不错的选择。使用相同的字符集从“编码文本”解码为String
。
当您将任意二进制数据转换为文本时,请使用base64编码,例如通过this public domain Base64 encoding library。
基本上,当您使用String(byte[])
或String(byte[], String)
构造函数创建新字符串时,您会说,“这是真正的文本数据 - 请将其解码为字符串。”当数据实际上是加密的结果时,它的不是文本数据......它是一串任意字节。