RSA 解密无法处理不明确的异常

时间:2021-07-19 02:38:10

标签: c# encryption cryptography rsa .net-core-3.1

我试图在 dot net core 中使用 RSA 加密一串信息,目的是只加密纯文本并将其发送到运行 PHP/MySQL 的服务器并存储加密信息。服务器不会发送任何确认或其他数据作为回复,因此这是一种单向通信(如果我可以说的话)。 为此,我提供了三种方法,一种生成 2048 的 Keypair,并将信息存储在 List(不是 RSAParameter)中并返回,另外两种方法是加密和解密方法。 问题是加密工作正常,公钥作为模数,公共指数作为指数,而在解密时,私钥作为模数,公共指数作为指数,私有指数“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));
    }

1 个答案:

答案 0 :(得分:0)

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

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

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 对象。

相关问题