2012-03-12 54 views
0

我正在使用Blowfish实现一个简单的密码存储。一切都很好,直到我尝试了几个不同的密码/组合键,并且遇到了大量解密值仍然是垃圾的实例。Java 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()); 
     } 
    } 

} 

回答

4

不要这样做:

return new String(cipher.doFinal(toEncrypt.getBytes())); 

您使用平台默认编码遍布整个地方。 不要这样做。它会丢失数据。

当您将真正的文本转换为字节(例如加密时)时,请使用特定的字符集 - UTF-8是一个不错的选择。使用相同的字符集从“编码文本”解码到String

当您将任意二进制数据转换为文本时,请使用base64编码(例如,通过this public domain Base64 encoding library

基本上,当您使用String(byte[])String(byte[], String)构造函数创建一个新字符串时,您会说:“这是真正的文本数据 - 请将其解码为字符串。”当数据实际上是加密的结果时,它是而不是文本数据......它是一个任意的字节串。

+0

好吧,我使用了Apache Base64实现,而不是做这项工作。 – user1016765 2012-03-12 16:08:51