2013-05-16 142 views
2

我正在開發一個跨平臺的加密系統。其中一個要求是在應用程序代碼中輕鬆加密和解密字符串。編碼和解碼UTF-8字節數組和字符串

加密類完美地工作,但我在Java端的字符串編碼遇到麻煩。

目前,我有以下的靜態方法:解密時

public static String encrypt(String key, String data) 
{ 
    byte[] decoded_key; 
    byte[] decoded_data; 
    try 
    { 
     decoded_key = key.getBytes("UTF-8"); 
     decoded_data = data.getBytes("UTF-8"); 
    } 
    catch (Exception e) 
    { 
     //Not Supposed to happen. 
     throw new RuntimeException(); 
    } 

    if(decoded_key.length != 16) 
     throw new IllegalArgumentException("Key length must be of 16 bytes. Given is " + decoded_key.length + "."); 

    try 
    { 
     return(IOUtils.toString(encrypt(decoded_key, decoded_data), "UTF-8")); 
    } 
    catch (Exception e) 
    { 
     //Not Supposed to happen. 
     throw new RuntimeException(); 
    } 
} 

public static String decrypt(String key, String data) 
{ 
    byte[] decoded_key; 
    byte[] decoded_data; 
    try 
    { 
     decoded_key = key.getBytes("UTF-8"); 
     decoded_data = data.getBytes("UTF-8"); 
    } 
    catch (Exception e) 
    { 
     //Not Supposed to happen. 
     throw new RuntimeException(); 
    } 

    if(decoded_key.length != 16) 
     throw new IllegalArgumentException("Key length must be of 16 bytes. Given is " + decoded_key.length + "."); 

    try 
    { 
     return(IOUtils.toString(decrypt(decoded_key, decoded_data), "UTF-8")); 
    } 
    catch (Exception e) 
    { 
     //Not Supposed to happen. 
     throw new RuntimeException(); 
    } 
} 

我的單元測試失敗。我跑了一個測試,我比較了編碼的UTF-8數據的一個字節數組encoded_dataIOUtils.toString( encoded_data , "UTF-8").getBytes("UTF-8"),由於某些原因,他們竟然是完全不同的數組。難怪我的解密算法失敗了。

從java字符串轉換爲UTF-8字節數組並返回到java字符串的正確過程是什麼?

+0

爲什麼你首先將字符串表示爲「鍵」?據推測他們是任意字節?您可能首先將它們轉換爲字符串,從而破壞了您的密鑰。 – jtahlborn

+0

業務需求。我的加密類使用字節。 – elite5472

+0

你錯過了我的觀點。你怎麼把鑰匙保持爲字符串而不破壞它們? – jtahlborn

回答

4

問題是您正在將您的加密數據轉換爲字符串。加密的數據是二進制的,而不是String數據。 UTF-8是一種具有特定編碼格式的字符集。任意二進制數據是而不是有效的UTF-8數據。當您將加密數據轉換爲字符串時,「無效」字符很可能會被?無效字符替換。

如果要將任意的二進制數據(又名加密數據)轉換爲字符串,則需要使用像Base64這樣的二進制 - >文本轉換。

+0

我給你的答案增加了一個例子。謝謝您的幫助。 – elite5472

0

我會嘗試首先檢查加密方法的輸出是否與您期望的單元測試相符。

此外,加密後使用Base64是一個不錯的主意,因此您可以將其轉換爲字符串。

另一個常見問題是將int轉換爲字節,就好像它們是無符號整數一樣。字節範圍是-128到127.

+0

這些方法不是遞歸的,它們採用字符串,它們調用採用byte []的方法。 – jtahlborn

+0

哎呀,你說的對,那是一個奇怪的多態使用。我想象其他方法有一些重複的代碼/檢查。 – Alex

+0

這並不奇怪,它們都是解密的,但對於不同類型的參數。字符串版本準備字節數組方法的所有內容。 – elite5472