首页 文章

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

提问于
浏览
0

我是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 回答

  • 0

    在您的Java代码中,您将模数和指数编码为 Base64 字符串,但是您通过使用 string encoding (例如UTF-8)进行解码将这些转换为字节数组,这会给您伪造的字节值 . 这为您提供了与您预期完全不同的RSA密钥:

    孙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");
    

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

    孙RSA公共密钥,1024位模数:128329253200625851747417306407495181460638722403079978934516135424027698446198581565013203888628021918042144433585511434660221274570695228957705446643239452347022609986771847076542293947545868471690675464836702700925020694185362910844461481736938124375366838112503820421836105957170854998527632432367452987301公用指数:65537

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

    “P2ENQbBu3rpBffnzbOj6MLCGBABclQnVY6QpHJ54uXZnKSd2Ll9fJ6g 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
    

    尝试使用Base64解码.NET平台上的字符串,看它是否与Java平台上的解码结果相匹配 .

相关问题