要解密的数据超过此模数128字节的最大值,同时加密Android中的数据和WCF Web服务中的解密

时间:2014-06-20 07:24:25

标签: android asp.net wcf rsa encryption-asymmetric

我是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.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 个答案:

答案 0 :(得分:0)

在Java代码中,您将模数和指数编码为 Base64 字符串,但是您通过使用字符串编码进行解码将这些字符串转换为字节数组(例如,UTF -8)它给你伪造的字节值。这给你一个完全不同的RSA密钥:

Sun RSA公钥,1375位   模量:750169282846494125860884712723073313436806987678989257696854519163422196468501094334772708285571263987960096312310946772203386096382092764988823316042225715695209682181694351362408270131738979229545667503402617569939108631330090897309670319383704572983438399762295114985980168234669536869729771611691862551491497864929321166916789165923322527018195770714618713254889722551163557798154618552019060264304749542004029   公众指数:1095844162

您的密文是模数1375,而不是1024,因此错误字符串是正确的。模数为1375(172字节)的Java生成的密文超出了.NET代码的模数,该代码仍然是1024(限制为128字节)。

相反,如果您使用Base64对这些字符串进行解码,例如:

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

然后你会得到你想要的钥匙:

Sun RSA公钥,1024位   模量:128329253200625851747417306407495181460638722403079978934516135424027698446198581565013203888628021918042144433585511434660221274570695228957705446643239452347022609986771847076542293947545868471690675464836702700925020694185362910844461481736938124375366838112503820421836105957170854998527632432367452987301   公共指数:65537

并且您的Java代码将产生以下结果:

“P2ENQbBu3rpBcrfnzbOj6MLCGBABclQnVY6QpHJ54uXZnKSd2Ll9fJ6g + avsvbWib9SNKsL9Yx + PeRdC20W6BXfblSnXMAbZxJ2VQCQho44rR + k6B9HrB2i0zl9pdLSRxm9k0poQVG1I / yplmK1H9TGqlZp1oYnbzWrS8JiRd5w =”

并且您的.NET代码将正确解密为“Manchester United”。

编辑:

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平台上的解码结果相匹配。