我是Android开发人员 . 手头的任务是使用RSA算法通过提供给我的公钥模数和指数加密我的Android应用程序中的数据,然后通过网络将其通过JSON字符串发送到.Net Web服务 . 此Web服务将解密数据并进一步使用它 .
我用来加密数据的代码如下:
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 = 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);
此处发生错误:byte [] 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
但是,我无法实施这些建议 . 任何帮助将不胜感激 . 谢谢!
1 回答
在您的Java代码中,您将模数和指数编码为 Base64 字符串,但是您通过使用 string encoding (例如UTF-8)进行解码将这些转换为字节数组,这会给您伪造的字节值 . 这为您提供了与您预期完全不同的RSA密钥:
孙RSA公共密钥,1375位模数:750169282846494125860884712723073313436806987678989257696854519163422196468501094334772708285571263987960096312310946772203386096382092764988823316042225715695209682181694351362408270131738979229545667503402617569939108631330090897309670319383704572983438399762295114985980168234669536869729771611691862551491497864929321166916789165923322527018195770714618713254889722551163557798154618552019060264304749542004029公用指数:1095844162
您的密文的模数为1375,而不是1024,因此错误字符串是正确的 . 模数为1375(172字节)的Java生成的密文超出了.NET代码的模数,该代码仍为1024(限制为128字节) .
相反,如果您使用Base64对这些字符串进行解码,例如:
然后你会得到你想要的钥匙:
孙RSA公共密钥,1024位模数:128329253200625851747417306407495181460638722403079978934516135424027698446198581565013203888628021918042144433585511434660221274570695228957705446643239452347022609986771847076542293947545868471690675464836702700925020694185362910844461481736938124375366838112503820421836105957170854998527632432367452987301公用指数:65537
并且您的Java代码将产生以下结果:
“P2ENQbBu3rpBffnzbOj6MLCGBABclQnVY6QpHJ54uXZnKSd2Ll9fJ6g avsvbWib9SNKsL9Yx PeRdC20W6BXfblSnXMAbZxJ2VQCQho44rR k6B9HrB2i0zl9pdLSRxm9k0poQVG1I / yplmK1H9TGqlZp1oYnbzWrS8JiRd5w =”
并且您的.NET代码将正确解密为“曼联” .
编辑:
Base64.decode应该与DatatypeConverter.parseBase64Binary的输出匹配 . 我通过这个循环获得的输出:
这是:
尝试使用Base64解码.NET平台上的字符串,看它是否与Java平台上的解码结果相匹配 .