如何在.Net Core中使用RSA加密数据并在Java中解密数据?

问题描述

我想使用RSA和公用/专用密钥在c#(server / .Net Core)中加密一个字符串,并在java(client)中对其进行解密。 C#端同时具有私钥和公钥,而Java端应使用公钥进行加密和解密。

这些是键:

static string  privateKey = "<RSAkeyvalue><Modulus>cBO/qYQLb376JT2QuPRnTi7Q24tgsZmg12TGGzYebXQtOH8+FDmBhkcMUt9+oLT7H5pKZKI8ql7eVKbK7rY7OAKBQd4g6BRG+09npObRX4zInZjRsqr6wzCcAul5ml+qVw765NRFlsVXzd5cYDp9+aTk=</Modulus><Exponent>AQAB</Exponent><P>2lTMG9Kxa1IH/Heo/eiYVb+7+lY3Lp+PcQ6NG866mqPlgEeuh3dc2DjAqira665l+GS5X6rM775PSWIU+tCTow==</P><Q>2w235CmX9NPRSmeXFiERm3gDUjl7jPsA+ynZAEBuVD/UYZ/QfAtSwoW9puWbLos0W1YfKxmxcXRtZaGl5Mz9cw==</Q><DP>oVE8SmZ/rsM6oWEsnQbJ37m+Q7aGKU2955QP0PcLS41D2mecXf1kvWIZgOIPRUpjj4ekrDoAGDfuT1NIGxYXrw==</DP><DQ>2rq4BHwD39QiB8moc9BRZIxRxKjhVcTNFf6TUE0F3dpel5yc8T/dQ5+H4D8k1TTq8sjsFn1xUXiqrAtFO1H1QQ==</DQ><InverseQ>lW6iyrtSYGK0ehBMLPEGbHlu7e5TiBhVDPuqmkl5K7arQXlPevjplYKkvxOWSak6GAjZJkj9tOEbqnQ3YGSFXA==</InverseQ><D>fSdbnllNf8iMcR1bfohxXN1cpqDDq6B5XDZAw64Jig2wt0cad4BYkqgbJpUx/6MTMzxSZs8qjfuiZYvvnl/wieGoOZWx78mjSLz5bl5QKcIjTUirUX1jzcguLZJXJnDpZQfjLui2e2l69b/5c62iEB0dSd7nHrvYYV4YQALLHgE=</D></RSAkeyvalue>";//rsa1.ToXmlString(true);
static string  publicKey = "<RSAkeyvalue><Modulus>cBO/qYQLb376JT2QuPRnTi7Q24tgsZmg12TGGzYebXQtOH8+FDmBhkcMUt9+oLT7H5pKZKI8ql7eVKbK7rY7OAKBQd4g6BRG+09npObRX4zInZjRsqr6wzCcAul5ml+qVw765NRFlsVXzd5cYDp9+aTk=</Modulus><Exponent>AQAB</Exponent></RSAkeyvalue>";

c#中的加密方法

 static string Encrypt(string text)
    {
        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(publicKey);

        UTF8Encoding encoding = new UTF8Encoding();
        byte[] textBytes = encoding.GetBytes(text);
        byte[] encryptedOutput = rsa1.Encrypt(textBytes,false);
       // byte[] encryptedOutput = rsa1.Encrypt(textBytes,RSAEncryptionPadding.OaepSHA1);
        string outputB64 = Convert.ToBase64String(encryptedOutput);

        return outputB64;
    }

c#中加密方法输出(测试数据为:“ 123”):

 static String mydata="AynqFwY2BMb7q6DXEOPiFSmqTjt3k+yRmkhU2QyEGoVR8SzcenUec0PFWERLAZmarq/Gxp7gJSf1MNHyTQRjTPaMqao5PXHb+Cl7p+CiXtt2hSPZesRI7APGOYhN6Zvmu+uIDEqdbcpfrXuY+4kY8eFnWZ+rnX/FXm5cHEMrnxQ=";

Java中的解密方法

   static String Decrypt(String encodedString) {
    try {
        byte[] modulusBytes = Base64.getDecoder().decode(publicKey);
        byte[] exponentBytes = Base64.getDecoder().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/ECB/PKCS1PADDING");
        cipher.init(Cipher.DECRYPT_MODE,pubKey);

        byte[] cipherData = Base64.getDecoder().decode(encodedString);
        byte[] plainBytes = cipher.doFinal(cipherData);
        return new String(plainBytes,"UTF-8");

    } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | UnsupportedEncodingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException err) {
        System.out.println(err.getMessage());
    }
    return "Error";
}

似乎问题出在Java函数的这一行:

Cipher cipher = Cipher.getInstance(RSA/ECB/PKCS1Padding);

在这行的c#函数中设置了true和false,但是不起作用:

byte[] encryptedOutput = rsa1.Encrypt(textBytes,false);

之后便决定将其替换为:

byte[] encryptedOutput = rsa1.Encrypt(textBytes,RSAEncryptionPadding.OaepSHA1);

没有用,并测试了两个函数中的所有填充类型,并检查了所有填充,但没有用。

我在this post中检查了解决方案,但我认为问题不在于填充,可能是因为对字符串进行了编码和解码。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)