我正在使用RSA加密來加密C#中的一些數據。現在我想用Java解密加密的數據。 但我遇到了一些問題。在Java中解密來自C#的RSA加密數據。加密數據的格式?
主要的問題可能是從c#到Java的加密消息。 在C#中我們無符號字節,字節序是不同
因此,爲了測試我轉換byte
陣列加密的數據在C#中的sbyte
陣列,並得到它的字符串表示。 然後我將字節數組的字符串表示複製到我的java代碼中,並將其轉換回'byte'數組。在那之後,我將數組倒過來以匹配java的字節順序。
但是,如果我嘗試這是像上面所傳送的數據進行解碼,我得到以下異常:
javax.crypto.BadPaddingException: Message is larger than modulus
加密和C#到C#解密工作,以及從Java到Java。只有C#到java將無法工作。 (要加密的字符串長度爲7個字符,所以它不是很長)
我將c#中的公鑰轉換爲BigInteger
。公共密鑰從RSAParameters
交付:
public byte[] RSAEncrypt(byte[] data, RSAParameters param, bool padding) {
using (RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024)) {
rsaProvider.ImportParameters(param);
byte[] modulusArray = param.Modulus;
byte[] exponentArray = param.Exponent;
BigInteger modulusBigInt = new BigInteger(modulusArray);
BigInteger exponentBigInt = new BigInteger(exponentArray);
encryptedData = rsaProvider.Encrypt(data, false);
return encryptedData;
}
}
之後,我複製模的字符串表示和指數到我的Java代碼,創建從他們新BigInteger
並創建公共密鑰:
BigInteger modulusBigInt = new BigInteger(modulusBytesStr);
BigInteger exponentBigInt = getBigIntFromByteString(exponentBytesStr);
Key pK = getPublicKey(modulusBigInt, exponentBigInt);
然後我嘗試對數據進行解密(其中數據是予從C#傳遞到Java等中描述上面的字節數組):
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, pK);
decryptedData = cipher.doFinal(data);
但是,如果我嘗試這樣做,我會得到上述異常。我想,公鑰應該是對的。至少我有相同的BigInteger
模數和指數在c#和java中的值。填充也是相同的。 所以我假設我的加密數據的格式有問題。它應該具有哪些fromat?
我也看到了這個問題:RSA .NET encryption Java decryption 但即使是我不知道是什麼格式我的數據到encryspt /解密應該有
編輯:嘗試在C#中的加密字節轉換爲Base64 String
和java將其轉換回字節。也不能正常工作
編輯2:如果我使用var key = rsaProvider.ToXmlString(true);
來獲取公共密鑰的xml represantation並將模數和指數的xml字符串放入我的java代碼中,將它們從Base64字符串轉換爲字節數組和字節數組到BigInteger的,然後我得到的BigInteger的曾在C#中的模數的BigInteger的另一個價值,但我得到follwing這個值異常:javax.crypto.BadPaddingException: Decryption error
EDIT3:發現我的錯誤:對於簡單的測試我只是使用的私有我在C#代碼中生成的密鑰在java中解密。但在我的java代碼中,我試圖從私鑰生成公鑰。
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pK = kf.generatePublic(keySpec);
這顯然是錯誤的。所以我改變了這個:
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulusBigInt, exponentBigInt);
KeyFactory kf = KeyFactory.getInstance("RSA");
Key key = kf.generatePrivate(keySpec);
它的工作。那也是爲什麼GregS的方法處理(有沒有「公鑰」 /「專用密鑰」生成和解密是不是在方法的Java編譯使用)
建議:不要嘗試加密和解密開始。找出一種將C#中的二進制數據傳輸到Java的方法,然後一旦這部分工作,就在它上面加密。 – zebediah49
想出了一個辦法:使用base64字符串(就像我第一次嘗試,在我嘗試直接傳輸字節之前,因爲沒有任何工作)。所以,正如你可以在我的EDIT2中看到的,base64字符串也不起作用。基於base64字符串,模數的BigInteger值在c#和java中是不同的。 – Rul3r