1

在下面的代码片段中,我尝试以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¬∙:╪⌡¶。为什么 ?如何以正确的字符串格式打印它?

4

4 回答 4

0

大多数加密算法(包括河豚)处理二进制数据,这意味着它将接收二进制数据并拆分已由算法转换的二进制数据(使用提供的规范)。

二进制数据,如您所知,字符串数据是 !=,但是二进制数据可以表示为字符串数据(使用十六进制、base64 等)。

如果我们查看您的示例代码,我们可以看到这一行:

byte encrypted[] = cipher.doFinal(input.getBytes());

这是它一步一步做的事情:

  1. 它首先使用平台的默认字符集(不推荐,但不相关)将字符串数据转换为等效的二进制数据。

  2. 它将二进制数据(以字节数组的形式)传递给方法 doFinal()。

  3. doFinal() 方法正在通过此行之前的语句中指定的规范(Blowfish,加密)处理此字节数组。

  4. doFinal() 语句返回一个字节数组,该数组表示已处理(在您的情况下为加密)数据。

由于加密操作的性质,数据最初来自字符串的事实不再相关,这并不能说明数据的来源或类型。加密字节数组现在包含可能不是有效字符集编码字符串的数据。尝试使用字符集来解码字符串很可能会导致垃圾输出,因为二进制数据不再是有效的字符串。

但是,二进制数据可以通过输出实际字节的VALUE来直接表示,而不是 charset 等效映射是什么(例如,一个字节可能有 97 的值,用十六进制表示为:0x61 但通过 ASCII 解码得到字符'一个')。

考虑此代码以十六进制输出您的加密数据:

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);

PS:不要在没有任何参数的情况下使用 getBytes() !提供您自己的字符集,例如 UTF-8。执行以下操作:

byte encrypted[] = cipher.doFinal(input.getBytes(Charset.forName("UTF-8")));
于 2013-08-25T20:00:01.287 回答
0

以 Base64 编码对字节进行编码(如何在 Java 中将字节数组转换为 Base64?

或 Hex:如何在 Java 中将字节数组转换为十六进制字符串?

System.out.println(Hex.encodeHexString(bytes));

于 2013-08-15T13:17:19.980 回答
0

您可以使用来自common-codec 的Base64编码。

    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==
于 2013-08-15T13:26:16.043 回答
0

您可以尝试:

new String(bytes, StandardCharsets.UTF_8)
于 2020-02-10T02:14:53.143 回答