简体   繁体   English

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

[英]RSA Decryption not working with an ambiguous exception

I am trying to encrypt a string of information using RSA in dot net core, the intention is to only encrypt the plain text and send it to a server running PHP/MySQL and store the encrypted information.我试图在 dot net core 中使用 RSA 加密一串信息,目的是只加密纯文本并将其发送到运行 PHP/MySQL 的服务器并存储加密信息。 the server does not send any confirmation or other data in reply, so it is a one-way communication (if I could say).服务器不会发送任何确认或其他数据作为回复,因此这是一种单向通信(如果我可以说的话)。 for this purpose I have three methods, one that generates a Keypair of 2048, and stores the information in a List (not the RSAParameter) and returns, the other two methods are encryption and decryption methods.为此,我提供了三种方法,一种生成 2048 的 Keypair,并将信息存储在 List(不是 RSAParameter)中并返回,另外两种方法是加密和解密方法。 The problem is the Encryption works fine with the public key as modulus and public exponent as an exponent, while at the decryption, with the private key as modulus, public exponent as an exponent, and the private exponent "D" as a private exponent, I am getting the exception " Modulus and Exponents are required fields", if I remove the "D" an exception of "Invalid Data Length for this Key size" is thrown, I am not so good at a mathematical aspect of RSA.问题是加密工作正常,公钥作为模数,公共指数作为指数,而在解密时,私钥作为模数,公共指数作为指数,私有指数“D”作为私有指数,我收到异常“模数和指数是必填字段”,如果我删除“D”,则会抛出“此密钥大小的无效数据长度”的异常,我不太擅长 RSA 的数学方面。 I have also tried every method of getting bytes ( Encoding, Covert, etc).我还尝试了各种获取字节的方法(编码、隐蔽等)。 Below are the three methods I am using.以下是我正在使用的三种方法。

Method to Generate Keypair and other Parameters:生成密钥对和其他参数的方法:

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;
    }

The Encryption Method加密方法

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));
    }

and finally the Decrypt Method:最后是解密方法:

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));
    }

Here is a Minimum Working Example (MWE) using your code as a starting point.这是使用您的代码作为起点的最小工作示例 (MWE)。 As I commented, you just need to import your private/public key.正如我所评论的,您只需要导入您的私钥/公钥。 No need to supply Exponent or D .无需提供ExponentD

(by the way, you are converting to-and-from binary and string types all over the place. I suggest you base your whole RSA code on byte[] and only convert back to string if/when you need to. The below code is written to match your supplied signatures) (顺便说一句,您正在到处转换二进制和字符串类型。我建议您将整个 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));
    }
}

Also don't forget to dispose your RSA objects.也不要忘记处理您的 RSA 对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM