为什么我没有以字符串格式获得输出?

时间:2013-08-15 13:14:51

标签: java cryptography bytearray

在下面的代码片段中,我尝试以简单的字符串格式打印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 个答案:

答案 0 :(得分:0)

使用Base64编码(How do I convert a byte array to Base64 in Java?

对字节进行编码

或Hex:How to convert a byte array to a hex string in Java?

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

答案 1 :(得分:0)

您可以使用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==

答案 2 :(得分:0)

大多数加密算法(包括blowfish)都处理二进制数据,这意味着它会将二进制数据输入并拆分由算法转换的二进制数据(使用提供的规范)。

二进制数据,如你所知!=字符串数据,但二进制数据可以表示作为字符串数据(使用hex,base64等)。

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

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

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

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

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

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

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

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

    但是,二进制数据可以通过输出实际字节的 VALUE 直接表示,而不是charset等效映射的值(例如,一个字节的值可能为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")));
    

答案 3 :(得分:0)

您可以尝试:

new String(bytes, StandardCharsets.UTF_8)