2011-11-02 147 views
0

我對Java加密/解密並不瞭解,因爲我的要求很簡單,將一行文本加密爲十六進制字符串(因此它可以放在瀏覽器的URL中),我複製從互聯網下面的代碼,它的工作原理,但只有在Windows(XP/7),在Mac上解密的字符串是完全混亂,請你幫我找出哪裏錯了?Mac OS上的加密/解密錯誤

public static String encrypt(String content, String password) throws NoSuchAlgorithmException, 
    NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, 
    BadPaddingException 
{ 
    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
    kgen.init(128, new SecureRandom(password.getBytes())); 
    SecretKey secretKey = kgen.generateKey(); 
    byte[] enCodeFormat = secretKey.getEncoded(); 
    SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    byte[] byteContent = content.getBytes("utf-8"); 
    cipher.init(Cipher.ENCRYPT_MODE, key); 
    byte[] result = cipher.doFinal(byteContent); 
    return parseByte2HexStr(result); 
} 


public static String decrypt(String contents, String password) throws NoSuchAlgorithmException, 
    NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
{ 
    byte[] content = parseHexStr2Byte(contents); 
    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
    kgen.init(128, new SecureRandom(password.getBytes())); 
    SecretKey secretKey = kgen.generateKey(); 
    byte[] enCodeFormat = secretKey.getEncoded(); 
    SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.DECRYPT_MODE, key); 
    byte[] result = cipher.doFinal(content); 
    return new String(result); 
} 


public static String parseByte2HexStr(byte buf[]) 
{ 
    StringBuffer sb = new StringBuffer(); 
    for(int i = 0; i < buf.length; i++) 
    { 
     String hex = Integer.toHexString(buf[i] & 0xFF); 
     if(hex.length() == 1) 
     { 
      hex = '0' + hex; 
     } 
     sb.append(hex.toUpperCase()); 
    } 
    return sb.toString(); 
} 


public static byte[] parseHexStr2Byte(String hexStr) 
{ 
    if(hexStr.length() < 1) 
     return null; 
    byte[] result = new byte[ hexStr.length()/2 ]; 
    for(int i = 0; i < hexStr.length()/2; i++) 
    { 
     int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); 
     int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); 
     result[i] = (byte) (high * 16 + low); 
    } 
    return result; 
} 
+1

SecureRandom實現不同 – thejh

回答

1

不要從「互聯網」複製代碼,因爲有很多垃圾在那裏,因爲你正在找出困難的方式。此代碼至少有2個重要的錯誤。

  1. 錯誤地假定如果您向種子提供SecureRandom,該種子是用於種子SecureRandom實例的唯一數據。
  2. 使用String.getBytes()方法中的默認字符集。幾乎總是應該明確指定用於加密的UTF-8字符集。

在你的情況#1可能是問題,#2可能不會傷害你。

正確的解決方案是使用正確的基於密碼的加密(PBE)算法。不幸的是,Sun提供商不支持任何基於AES的PBE算法。如果將bouncycastle提供程序添加到項目中,則可以獲得基於AES的PBE算法。

+0

謝謝你的幫助 – Mike