RSA 解密不适用于不明确的异常

RSA Decryption not working with an ambiguous exception

我正在尝试在 dot net core 中使用 RSA 加密一串信息,目的是仅加密纯文本并将其发送到服务器 运行 PHP/MySQL 并存储加密的信息。服务器不发送任何确认或其他数据作为回复,因此这是一种单向通信(如果我可以说的话)。 为此我有三种方法,一种生成2048的Keypair,将信息存储在一个List(不是RSAParameter)和returns中,另外两种方法是加密和解密方法。 问题是加密工作正常, public 密钥作为模数, public 指数作为指数,而在解密时,私钥作为模数, public 指数作为指数,和私有指数“D”作为私有指数,我得到异常“模数和指数是必填字段”,如果我删除“D”抛出“此密钥大小的无效数据长度”异常,我是不太擅长RSA的数学方面。我还尝试了每种获取字节的方法(编码、隐蔽等)。以下是我正在使用的三种方法。

生成密钥对和其他参数的方法:

public static List<string> RsaKeyGen()
    {
       List<string> keyPair = new List<string>();

       RSA rsa = RSA.Create(2048);
       RSAParameters param = rsa.ExportParameters(true);
        

       keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPrivateKey()));
       keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPublicKey()));
       keyPair.Add(Convert.ToBase64String(param.Exponent));
       keyPair.Add(Convert.ToBase64String(param.D));


       return keyPair;
    }

加密方法

public static string RsaEncrypt(byte[] PUBLIC_KEY ,byte[] EXPONENT, string text)
    {
        RSA rsa = RSA.Create(2048);
     
        RSAParameters param = new RSAParameters();
        param.Modulus = PUBLIC_KEY;
        param.Exponent = EXPONENT;
        rsa.ImportParameters(param);

        return Convert.ToBase64String(rsa.Encrypt(Convert.FromBase64String(text), RSAEncryptionPadding.Pkcs1));
    }

最后是解密方法:

public static string RsaDecrypt(byte[] PRIVATE_KEY, byte[] EXPONENT, byte[] PEXPO , string DATA)
    {
        RSA rsa = RSA.Create(2048);

        RSAParameters param = new RSAParameters();
        param.Modulus = PRIVATE_KEY;
        param.Exponent = EXPONENT;
        param.D = PEXPO;

        rsa.ImportParameters(param);

        return Convert.ToBase64String(rsa.Decrypt(Convert.FromBase64String(DATA), RSAEncryptionPadding.Pkcs1));
    }

这是一个以您的代码为起点的最小工作示例 (MWE)。正如我评论的那样,您只需要导入 private/public 密钥。无需提供 ExponentD.

(顺便说一句,您正在到处转换二进制和字符串类型。我建议您将整个 RSA 代码基于 byte[] 并且只转换回字符串 if/when 你需要。下面的代码是为了匹配你提供的签名而编写的)

public class RsaMwe
{
    public static bool Demo()
    {
        var strings = RsaKeyGen();

        var privKey = Convert.FromBase64String(strings[0]);
        var pubKey = Convert.FromBase64String(strings[1]);

        var clearText = "Hello World!";
        var clearText64 = Convert.ToBase64String(Encoding.Default.GetBytes(clearText));

        var encrypted64 = RsaEncrypt(pubKey, clearText64);
        var decrypted64 = RsaDecrypt(privKey, encrypted64);

        return clearText == Encoding.Default.GetString(Convert.FromBase64String(decrypted64));
    }

    public static List<string> RsaKeyGen()
    {
        List<string> keyPair = new List<string>();

        using RSA rsa = RSA.Create(2048);

        keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPrivateKey()));
        keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPublicKey()));

        return keyPair;
    }

    public static string RsaEncrypt(byte[] pubKey, string clearText64)
    {
        using RSA rsa = RSA.Create(2048);
        rsa.ImportRSAPublicKey(pubKey, out _);

        return Convert.ToBase64String(rsa.Encrypt(Convert.FromBase64String(clearText64), RSAEncryptionPadding.Pkcs1));
    }

    public static string RsaDecrypt(byte[] privKey, string cypherText64)
    {
        using RSA rsa = RSA.Create(2048);
        rsa.ImportRSAPrivateKey(privKey, out _);

        return Convert.ToBase64String(rsa.Decrypt(Convert.FromBase64String(cypherText64), RSAEncryptionPadding.Pkcs1));
    }
}

另外不要忘记处理您的 RSA 对象。