2012-11-22 238 views
1

我正在製作一個系統,我想通過RSA驗證服務器的身份,但似乎無法讓服務器正確解密客戶端的消息。RSA身份驗證問題

公鑰和私鑰位於數組的插槽0中,mod位於插槽1中,因此它們的設置正確。

客戶端代碼

int keyLength = 3072/8;//RSA key size 
byte[] data = new byte[keyLength]; 

//Generate some random data. Note that 
//Only the fist half of this will be used. 
new SecureRandom().nextBytes(data); 

int serverKeySize = in.readInt(); 
if (serverKeySize != keyLength) {//Definitely not the right heard 
    return false; 
} 

//Take the server's half of the random data and pass ours 
in.readFully(data, keyLength/2 , keyLength/2); 

//Encrypt the data 
BigInteger[] keys = getKeys(); 
BigInteger original = new BigInteger(data); 
BigInteger encrypted = original.modPow(keys[0], keys[1]); 
data = encrypted.toByteArray(); 

out.write(data); 

//If the server's hash doesn't match, the server has the wrong key! 
in.readFully(data, 0, data.length); 

BigInteger decrypted = new BigInteger(data); 

return original.equals(decrypted); 

服務器端代碼

int keyLength = 3072/8;//Key length 
byte[] data = new byte[keyLength]; 

//Send the second half of the key 
out.write(data, keyLength/2, keyLength/2); 
in.readFully(data); 

BigInteger[] keys = getKeys(); 
BigInteger encrypted = new BigInteger(data); 
BigInteger original = encrypted.modPow(keys[0], keys[1]); 
data = original.toByteArray(); 

out.write(data); 

據我所知,落實是正確的但它似乎並沒有產生正確的輸出。也不,我不希望因各種原因使用密碼。

+0

當涉及到加密算法時,規則第一號決不會自己實現現有的算法。使用現有的已知是正確工作的實現,例如,由Java提供。 – Robert

回答

2

有一些關鍵細節未被考慮。您要應用RSA的數據必須編碼爲BigInteger x,其中0是< = x < n,其中n是您的模數。你沒有這樣做。事實上,因爲您正在用隨機數據填充整個數據陣列,所以無法保證。 PKCS#1填充算法旨在正確執行此操作,但由於您正在自行編譯,因此必須在代碼中修復此問題。另外,請仔細檢查BigInteger(byte[])構造函數和BigInteger.toByteArray()如何對整數進行解碼/編碼。天真地很多人只期望基本的256編碼,並忘記BigInteger也必須適應負整數。它通過使用ASN.1 DER整數規則來實現。如果正整數的高位字節大於等於128,則會添加前導零字節。