2014-06-20 53 views
0

我是Android開發人員。目前的任務是使用RSA算法通過提供給我的公鑰模數和指數對我的Android應用程序中的數據進行加密,然後通過網絡通過JSON字符串將其發送到.Net Web服務。該Web服務將解密數據並進一步使用它。在Android中加密數據和在WCF Web服務中解密數據時,要解密的數據超過128個字節的最大模數

,我用它來加密數據的代碼如下:

public String RSAEncrypt (final String plain) throws Exception 
{ 
    try{ 
     String strModulus = "tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U="; 
     String strExponent = "AQAB"; 
     byte[] modulusBytes = strModulus.getBytes(); 
     byte[] exponentBytes = strExponent.getBytes(); 
     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/ECB/PKCS1Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, pubKey); 

     byte[] plainBytes = new String("Manchester United").getBytes("UTF-8"); 
     byte[] cipherData = cipher.doFinal(plainBytes); 
     encryptedString = Base64.encodeToString(cipherData, Base64.NO_PADDING); 
    } 
    catch(Exception e){ 
     Log.e("Error", e.toString()); 
    } 

    return encryptedString; 
} 

上面的代碼給了我,我傳遞給.NET Web服務的字符串。但由於某種原因,Web服務無法正確解密這些數據,並出現錯誤: 要解密的數據超過128個字節的最大模數

我試圖幫忙,但我無法理解什麼正在發生。

我在我的代碼中做了如下修改: Cipher cipher = Cipher.getInstance(「RSA/ECB/PKCS1Padding」);而不是 密碼cipher = Cipher.getInstance(「RSA」);

在加密數據時還提供了'Base64.NO_PADDING'。

的ASP.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>tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U=</Modulus><Exponent>AQAB</Exponent><P>6e0nv7EBFBugtpoB+ozpg1J4js8E+DVyWCuBsERBPzqu4H7Z/oeLIRSC8Gi5GZgrCpBf3EvyIluM7rzaIfNThQ==</P><Q>x/29X9ns1WcXC42IJjLDjscz5ygdVh79dm8B2tQVbqwyhDsQ6OIOQdu5+eHf4hUMoTrM9KkS2F6FGlLXuaOFoQ==</Q><DP>kTS2LMaJ/dpce5zDx6w6s1q5HSSiWBSNIu/2s9zah448yXvUg6vNkD40PVk0NRAA/7C44H2AExWzOOqfmN17JQ==</DP><DQ>xtAx9drQPWnpl/uQUOEAVa0kpPTVDStrr9Q1FNTnpYkcAyYw7kLkB4anAIoSpk9kqdeprsNxz5VPXtbiTFMKYQ==</DQ><InverseQ>O0594NMjnjSp+/NAa1kQxoQNzn1qqq+p1Zb+kT3/jRc/0d7ZnqSSpxFMXfxx3yZkNAOPDOdbckPQbRZ13RKBHg==</InverseQ><D>bjVEagwvkrZaTt9CTW1hd3362weLFlX6DpE/3R3RcrpVfkSwKGpEhqGrNeeGPlsuqiaf5rAFir4eTqrF1QVliKsU4XE0RyzP5lHGc7dlX4DOHMjs2R9nNWv8QOTPoaRuLrLGorqBXlw/jQPxFI6gQzkIIjzuf//lDVnFam3dw4E=</D></RSAKeyValue>"); 

      string data2Decrypt = "SeuUUjdSbFQlcwaCFVZ9fN0t3aXpItXU4+pkuztVgky77SBokBATKj+56+irtCfT1lSGRZbbzgQTd8zpcjPsT6J+7AyBwRwuv418JyKINNxPsDVFKfupViu8MOoxWzjmjZE5p54AjByA6dzGSR9UogFHhFSMZWJ5OELwZFSz5wFHyMaeIm1UnEiRDDjPTY/aIuh56WnZPXUmP3D54bAwDXPFtY0JjjiyxZetnA"; 

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

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

發生該錯誤的位置: 字節[]平原= rsa1.Decrypt(encyrptedBytes,FALSE);

Decrypt是.Net本身的RSACryptoProvider類的一個函數。

我已經檢查像幾個環節: The data to be decrypted exceeds the maximum for this modulus of 128 bytes. RSA DECRYPTION c#

The data to be decrypted exceeds the maximum for this modulus of 128 bytes

不過,我不能夠實現的建議。任何幫助將不勝感激。謝謝!

回答

0

在Java代碼,必須編碼爲的Base64串的模數和指數,但通過使用字符串編碼解碼轉換那些字節陣列(例如UTF-8),讓你僞字節值。這是給你比您預期完全不同的RSA密鑰:

孫RSA公共密鑰,1375位 模量:750169282846494125860884712723073313436806987678989257696854519163422196468501094334772708285571263987960096312310946772203386096382092764988823316042225715695209682181694351362408270131738979229545667503402617569939108631330090897309670319383704572983438399762295114985980168234669536869729771611691862551491497864929321166916789165923322527018195770714618713254889722551163557798154618552019060264304749542004029 公用指數:1095844162

你的密文是在模數1375,而不是1024,所以錯誤字符串是正確的。 Java產生的模數1375(172字節)的密文超過.NET代碼的模數,該代碼仍然是1024(限於128字節。)

相反,如果你的Base64解碼這樣的字符串,例如:

byte[] modulusBytes = DatatypeConverter.parseBase64Binary("tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U="); 
byte[] exponentBytes = DatatypeConverter.parseBase64Binary("AQAB"); 

那麼你會得到你想要的關鍵:

孫RSA公共密鑰,1024位 模:128329253200625851747417306407495181460638722403079978934516135424027698446198581565013203888628021918042144433585511434660221274570695228957705446643239452347022609986771847076542293947545868471690675464836702700925020694185362910844461481736938124375366838112503820421836105957170854998527632432367452987301 公共exponen T:65537

和Java代碼將產品這樣的結果:

「P2ENQbBu3rpBcrfnzbOj6MLCGBABclQnVY6QpHJ54uXZnKSd2Ll9fJ6g + avsvbWib9SNKsL9Yx + PeRdC20W6BXfblSnXMAbZxJ2VQCQho44rR + k6B9HrB2i0zl9pdLSRxm9k0poQVG1I/yplmK1H9TGqlZp1oYnbzWrS8JiRd5w =」

和您的.NET代碼會被正確解密,以 「曼聯」。

編輯:

Base64.decode應該匹配DatatypeConverter.parseBase64Binary的輸出。輸出我用這個循環得到:

for (int i = 0; i < modulusBytes.length; i++) 
{ 
    System.out.print(" "); 
    System.out.print(modulusBytes[i]); 
} 
System.out.println(); 

是這樣的:

-74 -65 54 81 -9 -122 122 -43 123 -56 18 -100 56 -8 -59 77 107 59 -92 122 -86 -81 -2 88 40 -91 -116 81 -97 -57 27 -127 -25 10 101 -85 102 -61 -95 -71 29 69 6 115 25 -2 13 -104 -118 -117 40 74 91 -76 -51 -34 -44 -109 63 101 95 -68 47 -39 18 -33 89 119 -52 -67 -106 6 -92 0 47 125 -123 -80 -51 -68 -112 -38 45 106 -6 -46 -124 -2 -40 96 40 -37 28 -95 36 94 -106 80 -61 -6 -30 92 98 125 71 -30 25 -38 -71 -43 114 96 -111 -3 -102 37 97 56 -88 74 -108 76 76 -49 15 26 -97 -91 

嘗試在.NET平臺上的串Base64編碼解碼,看看它在Java平臺上的解碼結果相匹配。

+0

這是一個真正的好方案。這應該適用於我。唯一的問題是,Android不讓我使用'DatatypeConverter.parseBase64Binary',我不得不使用'Base64.decode()',它不提供所需的輸出。我試圖導入'javax.xml.bind.DatatypeConverter'的包,但無法正確實現。我很抱歉,但還有什麼可以滿足我的需求嗎? – Bot

+0

兩個Base64解碼器都應該產生相同的輸出,所以問題出在Base64.decode上,而不是加密上。看到我上面的編輯。 –

+0

此代碼在Java中完美工作。但在Android中不太好。在WCF中,當我解密使用Java代碼加密的字符串時,我得到了正確的值,但是我得到了Android的錯誤。問題是'byte [] cipherData'對於Java和Android來說是不一樣的。我似乎無法理解爲什麼。 – Bot