在以下代码段中,我尝试以简单的字符串格式打印encrypted array
。
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
SecretKey secretKey = keyGenerator.generateKey();
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
String input = "password";
byte encrypted[] = cipher.doFinal(input.getBytes());
String s = new String(encrypted);
System.out.println(s);
但是我得到的是`┐╫Y²▓ô┴Vh¬∙:╪⌡¶
。为什么 ?如何以正确的字符串格式打印它?
您可以使用Base64中的common-codec编码。
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
SecretKey secretKey = keyGenerator.generateKey();
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
String input = "password";
byte encrypted[] = cipher.doFinal(input.getBytes());
System.out.println(new String(Base64.encodeBase64(encrypted)));
输出:
8KA8ahr6INnY4qqtzjAJ8Q==
以Base64编码(How do I convert a byte array to Base64 in Java?)编码字节
或十六进制:How to convert a byte array to a hex string in Java?
System.out.println(Hex.encodeHexString(bytes));
[大多数密码算法(包括河豚)处理二进制数据,这意味着它将接收二进制数据并分割出已通过算法转换的二进制数据(具有提供的规范)。
二进制数据,如您所知!! =字符串数据,但是二进制数据可以表示作为字符串数据(使用十六进制,base64等)。
如果我们查看您的示例代码,我们将看到以下行:
byte encrypted[] = cipher.doFinal(input.getBytes());
这是它正在逐步执行的操作:
首先使用平台的默认字符集将字符串数据转换为等效的二进制数据(不推荐,但无关紧要)。
它将二进制数据(以字节数组的形式)传递给方法doFinal()。
doFinal()方法正在通过此行之前的语句中指定的规范来处理此字节数组(Blowfish,加密)。
doFinal()语句返回一个字节数组,该字节数组表示已处理(对于您而言,是加密的)数据。
由于加密操作的性质,数据最初来自字符串的事实不再重要,因此不能解释数据的来源或类型。现在,加密的字节数组包含的数据可能不是有效的字符集编码的字符串。尝试使用字符集对字符串进行解码很可能会导致垃圾输出,因为二进制数据不再是有效的字符串。
但是,二进制数据可以直接通过输出实际字节的VALUE来表示,而不是通过字符集等效映射来表示(例如,一个字节可能具有值97,以十六进制表示:0x61但已解码)通过ASCII生成字符'a')。
考虑此代码以十六进制输出您的加密数据:
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
SecretKey secretKey = keyGenerator.generateKey();
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
String input = "password";
byte encrypted[] = cipher.doFinal(input.getBytes());
StringBuilder str = new StringBuilder();
for(byte b:encrypted){
str.append(String.format("%02x", b));
}
String encData = str.toString();
System.out.println(encData);
P.S:不要在没有任何参数的情况下使用getBytes()!提供您自己的字符集,例如UTF-8。请执行以下操作:
byte encrypted[] = cipher.doFinal(input.getBytes(Charset.forName("UTF-8")));
您可以尝试:
new String(bytes, StandardCharsets.UTF_8)