首页 > 解决方案 > 使用 .NET 从公钥字节进行 RSA/ECB/PKCSPadding1 加密

问题描述

我希望 C# 代码使用 RSA/ECB/PKCSPadding1 密码和公钥的字节来加密一个小字符串(密码)。加密测试是使用私钥使用 Java 代码(明确支持此密码)对加密值进行解密。Java 代码如下所示:

static String decrypt(String encryptedB64, String privateKeyBase64)
{
    try {
        byte[] privateKeyBytes = Base64.decodeBase64(privateKeyBase64);
        Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");

        KeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        rsa.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(rsa.doFinal(Base64.decodeBase64(encryptedB64)), StandardCharsets.UTF_8);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

标签: c#.netencryptionrsax509

解决方案


更高版本的 dotnet 平台明确支持 PKCS1 填充。这段代码对我有用。我使用 C# 加密并确认我可以使用带有 RSA/ECB/PKCS1Padding 密码的 Java 进行解密。唯一的问题是我必须提前知道公钥中有多少位(例如 1024、2048)。

using System;
using System.Security.Cryptography;

class Program
{

    static void Main(string[] args)
    {
        String pubB64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCK8xP3JO4exQPIB2eDpAVXasM3YOoZN405HuaSjr1FVE0Z++jKrVhTiOYqiXX7ksChmoEt4uim+tWK/1SNpMyD/nl4SsQjkG0zRJr+kfP4owDnQdZRDPpLZABI2X5O6o5bgwPsxY3UfuenwrKc1/FQRITfaTp7nyoX956EZ9v4dQIDAQAB";
        String text = "abcdefg123456";
        byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(text);
        byte[] publicKeyBytes = Convert.FromBase64String(pubB64);

        var keyLengthBits = 1024;  // need to know length of public key in advance!
        byte[] exponent = new byte[3];
        byte[] modulus = new byte[keyLengthBits / 8];
        Array.Copy(publicKeyBytes, publicKeyBytes.Length - exponent.Length, exponent, 0, exponent.Length);
        Array.Copy(publicKeyBytes, publicKeyBytes.Length - exponent.Length - 2 - modulus.Length, modulus, 0, modulus.Length);

        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        RSAParameters rsaKeyInfo = rsa.ExportParameters(false);
        rsaKeyInfo.Modulus = modulus;
        rsaKeyInfo.Exponent = exponent;
        rsa.ImportParameters(rsaKeyInfo);

        byte[] encrypted = rsa.Encrypt(textBytes, RSAEncryptionPadding.Pkcs1);
        Console.WriteLine(Convert.ToBase64String(encrypted));

    }
}

推荐阅读