2015-11-02 50 views
0

我正在創建一個跨平臺的Android/Windows應用程序。解密Android RSA:無效的密文異常

我用這個代碼來生成在Android的公鑰,我可以從一個從Windows的應用程序生成的測試公鑰使用:

  String AppKeyPub = "MIGHAoGBAONcDWYnbGGOIG1wfHy8v54/2Ch2ZCewcM6TGGtnvHOa/53ekPlCYHXG5UDeaCUxPwPK" + 
"Fx9qikj04nxF+tKl9GnV4RS+3kDQPkunlJ4pk52PiKVGaVpOWOli1Y31zJJZ9ufqLySEycJVuqiI" + 
"Z9kektzkHdAIxNKlPDn4GQa2mjz/AgER"; 

      try { 
       // PREP PUBLIC KEY 
       byte[] decoded = Base64.decode(AppKeyPub,0); 
       org.bouncycastle.asn1.pkcs.RSAPublicKey pkcs1PublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(decoded); 
       BigInteger modulus = pkcs1PublicKey.getModulus(); 
       BigInteger publicExponent = pkcs1PublicKey.getPublicExponent(); 
       RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, publicExponent); 
       KeyFactory kf = KeyFactory.getInstance("RSA"); 
       PublicKey publicKey = kf.generatePublic(keySpec); 

我用這個代碼,然後加密測試消息:

byte[] input = "Hello from Android!".getBytes("UTF-8"); 
     Cipher cipher = Cipher.getInstance("RSA", "BC"); 
     cipher.init(Cipher.ENCRYPT_MODE, publicKey);     

     byte[] cipherText = new byte[cipher.getOutputSize(input.length)]; 
     int ctLength = cipher.update(input, 0, input.length, cipherText, 0); 
     ctLength += cipher.doFinal(cipherText, ctLength); 
     String encodedData = Base64.encodeToString(cipherText, messageCount); 
     System.out.println(new String(encodedData)); 
     System.out.println(ctLength); 

這是由Android生成的加密測試消息:

fy1l1g/Tpxer4mR3bO6WQdfmi93I/YjpZZ DGvIiZ6UU/VZWhnmgmuU1zM6EqwppqQTMkfsKPk5kAWhSYH8 + tbyvgh/Cd48rTKJ39MCfnwCNZvSvNKETZbhgy5fVGL/Uisn16AOae0DI4gV4kubrGswhEFUpyp8seAPclKgHbGuQ =

問題是,當我嘗試在Windows的應用程序失敗,出現錯誤消息對消息進行解密:

RSA/OAEP-MGF1(SHA -1):無效的密文

我試過不同的Android BC算法組合,它們都給了我相同的結果。我也試過no_wrap no_padding等。誰能告訴我我做錯了什麼?感謝您的任何建議。

+0

是Windows應用程序解密之前執行Base64編碼解碼? –

+0

不,你不是。你提供了一個雙端問題的一端。假設你沒有正確加密它是壓倒性的。 – EJP

回答

1

在Windows應用程序中有OAEP填充。至少在更高版本中,OAEP填充是默認設置。我就告訴你如何執行OAEP填充,因爲它是 - 可能是最安全的一個RSA - 可能是少爲人知的KEM方案後:

Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPADDING", "BC"); 
cipher.init(Cipher.ENCRYPT_MODE, publicKey);     
byte[] cipherText = new byte[cipher.getOutputSize(input.length)]; 
int ctLength = cipher.update(input, 0, input.length, cipherText, 0); 
ctLength += cipher.doFinal(cipherText, ctLength); 
+0

工作!馬爾滕你是一個救生員。我正在使用provider.getServices();但我從未在列表中看到過「RSA/NONE/OAEPPADDING」作爲選項?我會積極回答你的答案,但是現在我不能無緣無故地感謝這個問題的倒退。 – raximus

+1

有RSA // OAEPPADDING,它需要斜槓之間的某種兼容模式。 NONE可能是最好的,但ECB也是可能的(爲了與Oracle提供商兼容,但恕我直言不正確)。 –

+0

再次感謝馬滕。我已經提出了你的答案。現在讓加密工作朝另一個方向發展...... – raximus