2010-04-23 202 views
8

我使用RSA在JAVA上進行加密,並嘗試使用.NET進行解密。我包含了我的JAVA代碼和.NET代碼,希望有人對這類事情有一些經驗。Java RSA加密 - 解密.NET

Java代碼:

byte[] modulusBytes = Base64.decode("xTSiS4+I/x9awUXcF66Ffw7tracsQfGCn6g6k/hGkLquHYMFTCYk4mOB5NwLwqczwvl8HkQfDShGcvrm47XHKUzA8iadWdA5n4toBECzRxiCWCHm1KEg59LUD3fxTG5ogGiNxDj9wSguCIzFdUxBYq5ot2J4iLgGu0qShml5vwk="); 
byte[] exponentBytes = Base64.decode("AQAB"); 
BigInteger modulus = new BigInteger(1, modulusBytes); 
BigInteger exponent = new BigInteger(1, exponentBytes); 

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent); 
KeyFactory fact = KeyFactory.getInstance("RSA"); 
PublicKey pubKey = fact.generatePublic(rsaPubKey); 

Cipher cipher = Cipher.getInstance("RSA"); 
cipher.init(Cipher.ENCRYPT_MODE, pubKey); 

byte[] plainBytes = new String("big kitty dancing").getBytes("UTF-8"); 
byte[] cipherData = cipher.doFinal(plainBytes); 
String encryptedString = Base64.encodeBytes(cipherData); 

從這個Java代碼我拿encryptedString的這恰好是結果:

FoP4 + AAIH6hcabXnrvNG5YUk/nBv9n9HU0CAgZjkIWQIDjbOpSwoPVBFERrZ6641x2QaoJw5yv18XAay + 0WrCaSw4sveRX + hmPm5qeVUPcjoR4slsVZ/hBFJtAHj9tva4hOugWDZa9s3RVJlxkNfE + U +的Kt/YKLOi2EYbH05HjeM =

並嘗試使用以下.NET代碼進行解密

const int PROVIDER_RSA_FULL = 1; 
const string CONTAINER_NAME = "Tracker"; 

CspParameters cspParams; 
cspParams = new CspParameters(PROVIDER_RSA_FULL); 
cspParams.KeyContainerName = CONTAINER_NAME; 
RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(cspParams); 
rsa1.FromXmlString("<RSAKeyValue><Modulus>xTSiS4+I/x9awUXcF66Ffw7tracsQfGCn6g6k/hGkLquHYMFTCYk4mOB5NwLwqczwvl8HkQfDShGcvrm47XHKUzA8iadWdA5n4toBECzRxiCWCHm1KEg59LUD3fxTG5ogGiNxDj9wSguCIzFdUxBYq5ot2J4iLgGu0qShml5vwk=</Modulus><Exponent>AQAB</Exponent><P>+lXMCEwIN/7+eMpBrq87kQppxu3jJBTwztGTfXNaPUTx+A6uqRwug5oHBbSpYXKNDNCBzVm/0VxB3bo4FJx+ZQ==</P><Q>yasOGaJaE9xlF9T2xRuKeG9ZxCiyjhYaYB/mbtL+SIbtkRLi/AxaU4g2Il/UxhxhSXArKxIzV28zktispPJx1Q==</Q><DP>ueRgQIEFUV+fY979a1RgrVHIPpqEI1URhOMH3Q59oiXCcOumM5njyIHmWQxRAzXnG+7xlKXi1PrnRll0L4oOKQ==</DP><DQ>dfEMNgG1HJhwpxdtmqkYuoakwQvsIRzcIAuIAJh1DoWaupWJGk8/JEstHb1d+t7uJrzrAi2KyT/HscH2diE0YQ==</DQ><InverseQ>YoYF9PF6FiC0YngVeaC/eqt/ea8wMYNN3YO1LuzWpcy2exPRj2U0ZbWMvHXMUb4ea2qmhZGx1QlK4ULAuWKpXQ==</InverseQ><D>g1WAWI4pEK9TA7CA2Yyy/2FzzNiu0uQCuE2TZYRNiomo96KQXpxwqAzZLw+VDXfJMypwDMAVZe/SqzSJnFEtZxjdxaEo3VLcZ1mnbIL0vS7D6iFeYutF9kF231165qGd3k2tgymNMMpY7oYKjS11Y6JqWDU0WE5hjS2X35iG6mE=</D></RSAKeyValue>"); 

string data2Decrypt = "FoP4+AAIH6hcabXnrvNG5YUk/nBv9n9HU0CAgZjkIWQIDjbOpSwoPVBFERrZ6641x2QaoJw5yv18XAay+0WrCaSw4sveRX+hmPm5qeVUPcjoR4slsVZ/hBFJtAHj9tva4hOugWDZa9s3RVJlxkNfE+u+Kt/YKLOi2EYbH05HjeM="; 

byte[] encyrptedBytes = Convert.FromBase64String(data2Decrypt); 

byte[] plain = rsa1.Decrypt(encyrptedBytes, false); 
string decryptedString = System.Text.Encoding.UTF8.GetString(plain); 
+0

哦,並且我收到的錯誤是「壞數據」 – badMonkey 2010-04-23 13:24:22

+0

您好@badMonkey,我有一個問題。你從哪裏得到XML?我沒有那部分,它有很多參數(Q,P,DP,DQ,InverseQ,D)。我的java夥伴正在加密一個文本,而碰巧是我的C#開發人員應該解密它。他給了我模數和指數,我怎樣才能設法使用模數和指數來解密加密的字符串? – 2017-08-27 05:31:48

+0

我不太確定哪一個是哪一個,但我很確定這個紳士https://youtu.be/oOcTVTpUsPQ的這個很好的說明視頻解釋了我在之前的評論中提到的那些問題。祝你好運。 – 2017-08-27 05:45:52

回答

7

在Java方面,您需要使用"RSA/ECB/PKCS1Padding"作爲算法名稱。通過簡單的"RSA"名稱,Java不會添加C#實現期望的PKCS#1填充,因此「壞數據」。

填充是將輸入數據(您的編碼字符串)轉換爲與RSA模數(此處爲128字節)相同長度的稍大字符串。這對安全性很重要,並注入一些隨機性(同一個輸入字符串不會每次都產生相同的加密字符串,但解密過程將刪除該隨機性並恢復正確的字符串)。

+0

總是顯式地定義Java中的模式和填充,因爲沒有關於在不使用時會使用什麼的保證。我想知道C#/ .NET有一些相當的功能嗎? – laz 2010-04-23 15:29:03

+0

托馬斯我希望你總是在我有加密問題時!這絕對解決了這個問題。 laz - RSACryptoServiceProvider.KeyExchangeAlgorithm是您設置的屬性。默認(如Thomas Pornin指出的)是「RSA-PKCS1-KeyEx」。 – badMonkey 2010-04-24 13:24:31

+0

不可以。如果指定Cipher.getInstance(「RSA」),則會得到「RSA/ECB/PKCS1Padding」。 – 2010-04-24 13:28:51