2011-12-27 63 views
0

我正在開發一個使用RSA和RC4的小型身份驗證方案。在我目前的情況下,我試圖發送一個隨機生成的會話密鑰給客戶端,使用客戶端的公鑰加密。從那裏,客戶端將讀取會話密鑰,並使用其私鑰對其進行解密,然後將哈希發送回服務器(我不會進入更好的安全機制,因爲它們不是問題的一部分)。私鑰解密對稱密鑰,但在對稱密鑰聯網時給出不同結果?

目前,我已確認服務器具有客戶端公鑰的相同副本。我知道服務器正在使用客戶端的公鑰對隨機生成的會話密鑰進行加密。所以這裏很可能沒有問題。

我認爲問題在於密鑰的轉移。關鍵是字符串類型,並且作爲這樣初始化 -

String sessionKey = new BigInteger(128, server.random).toString(128); 

並使用DataOutputStream類被傳輸到客戶端 -

o.writeUTF(this.encryptedSessionKey); 

encryptedSessionKey是一個正常的字符串,沒有特定的編碼。我在想,也許,解密時,Java modified UTF-8編碼,會惡化會話密鑰。我解密作爲這樣 -

this.sessionKey = new String(cryptUtil.rsaDecrypt(clientPrivateKey, this.encryptedSessionKey.getBytes())); 
// Where encryptedSessionKey is read from the stream using i.readUTF(); 

將使用String.getBytes()上用Java編碼的字符串UTF-8修改(從DataInputStream.readUTF讀())來自沒有特定的編碼實例化的字符串返回不同的數據?

回答

2

我的猜測是,你正在做這樣的事情:

byte[] encryptedSessionKeyAsBytes = cipher.doFinal(...); 
String encryptedSessionKey = new String(encryptedSessionKeyAsBytes); 

這是不對的。 String構造函數使用默認平臺編碼將字節轉換爲字符。並且所有的字節序列都不能轉換爲字符。例如,如果您的默認編碼是ASCII,則所有負字節都不能轉換爲字符。

如果您必須傳輸二進制數據,然後將其傳輸爲字節(使用byte []類型),或使用Base64將字節轉換爲可打印的字符,並使用ASCII,ISO-8859-1或UTF - 無論編碼如何傳輸Base-64字符串。