无法在 .Net Core 中使用 RSA 私钥解密连接字符串

Unable to decrypt connection string using RSA private key in .Net Core

我能够使用带有 Encoding.UTF8 和 RSACryptoServiceProvider() 的 RSA public 密钥加密连接字符串。

但是当我试图解密它时,我正面临

"System.InvalidOperationException: XML 文档 (1, 2) 中存在错误。 ---> System.InvalidOperationException:出乎意料。”

"ConnectionStrings": {
    "ConnectionString": "JLR+q4Bf3HyHpmby2gBI/bQi2C3Oqun+4lemvsBxeXU6YjHnNvdq0q54gf4VVbHDDkx5a57cGNgsSkYWP5uzJtsmdLQnJU5kA4yRSdaKbUdxE1aVDJMcJneVsNo73CSGhXQcK9zN8ILZeD/a51bA9ap00vWfx4v/nvCTZe3s26g="
  };

public class HomeController : ControllerBase
{

    private ConnectionStrings connectionStrings { get; set; }


    public HomeController(IOptions<ConnectionStrings> settings)
    {
        connectionStrings = settings.Value;
    }


    public string Get()
    {
        string data = connectionStrings.ConnectionString;

        string path = @"C:\temp\privateKey.xml";
        var privateKey = System.IO.File.ReadAllText(path);

        var bytesCypherText = Convert.FromBase64String(data);
        var csp = new RSACryptoServiceProvider();

        var sr = new System.IO.StringReader(privateKey);

        XmlSerializer xs = new XmlSerializer(typeof(RSAParameters));

        var privKey = (RSAParameters)xs.Deserialize(sr); // says error with the XML
        csp.ImportParameters(privKey);

        var plaintext = csp.Decrypt(bytesCypherText, false);
        return Encoding.Unicode.GetString(plaintext);
    }

}

我正在使用 .NET CORE 框架,我遇到了很多 Whosebug 线程,并且知道我们可以通过配置生成器来完成它,但我很难找到如何去做。

我是.Net平台的初学者,所以请验证以上细节并帮助我获取解密文本。

您似乎在尝试使用 RSA 解密密码(例如 ConnectionString)。

public static void Main()
{
    var privateKey= "<RSAKeyValue><Modulus>qltOYNlEOWNS4ACtgcIDzBkEyvJafolqakvAvtZeM9Vy6CK+ZD8mo0Xn1LkFXLMWjuCZBzXvaaaL8QQhT2iB1Kxas+nfQbgHhbRcNFisgaBRYiA5ilDuYPRoGXPDhuxysvjy/00CPpErdNqc/lSElpwNv0P5fwlwqPdZhBOxSL2WkRPkirSq06apACJ9UIP9d3lmgBkKJigGGDaJOjSotvtWZpONhnyr2ncHmREpaJd4O5hjxOESztMEHZf/LpoYsopEAVk+HAYbGf1J3MbzeL0nHupSGdVCG+YpJw0dHvujZEW4Q3+Ir4lGjDnntxcvffFUdH+cPsQuZyKD7fZ1rQ==</Modulus><Exponent>AQAB</Exponent><P>zNHC2XnpbcBr9iLf7Z3AoKD2SjgRcql4wwb/BeGFDFqRxS00T1tYd83AK2mBG1aqdyZH1idicTEM1TlW8FwhaO3kk0PoveBV5SVm537J8eG7MZ4yH0bKFYg8RjdkfrZppYHVCXE6ubEGTGOQGxTjjcUaLD9uqoorwPHKtOq8nY8=</P><Q>1Oz5iFxSnrZtUXcPcLAjoIQex3zDmgONyQEzVHndLHF6BO/9k6Dur2UiRfXQPltzEFfP8zZj1z+C7iuKfjnhOsRVour2A4gDduyezaHLb/4kCht2Sx8NB3wduAtsZr+8UmRJPeLvkEcN8+e0kG1oFHibUn7LiJv+RK/0wyeBEwM=</Q><DP>u7idH3nvChpMWQFJv5zQSeh9EzUkOLU+63DkF93Edbgk1lVCFmGgSd2X/bHrFMVv41iAirT6MshD/MFa/11RebxfvOGG1VBhKW4ITLAWIs1DJozZX3UgDnAY3joyrzg8x+ag/NB8hGjNXwH5t/iDPxKhlGBm64NL6sExinOCf90=</DP><DQ>rluHUrRXK4QzLHyUdjCmW/EUy0JNYjb6ydhj0g8goB4kTxq+yT8FdTcZw7Qw3H9CT+W4cW7efwqRCrs443g+CUNw5MIGxomAXMgSmkydLI4tsOEgEw/QOYrXQziHgfQMIGPi3fyRM9IbiNj6MTKGAg1pEzqlLK6gnlp/0bbtqUU=</DQ><InverseQ>G9FE60+miTihgULQbXu2xl6hCsdSUN7P5AtzxoZQYh5TNhytkMhDw7CXPnGaXLUCt5KUA8hax+kM9XbxP1fheRAe0llf1k7f6PEaWotposAbcS3GYjL2zZzRZTppsF3HO8/NTR6auYcDlz9f66kJqMYGnWMe/NrLKuRc4/rmbIQ=</InverseQ><D>Amgz3U50llL+8sdPrEuvfgzEcpGmEa+jX0keuhORVS4o53rGMehqhVgRhIHwv3SQVwh5YQ60CUwfIhKq3dJeM0EULwKY8vbEtHDt9JdkKJi5Taei6H9oPtp1Nhbapmdk336BAHZ4F6Y5dPc5zKYpEW+3CgLN3aumedy02RbmJF7zgJ1X7XDe2/TS8Xy7bXAQWyGryQt242VDskI8300d47Xqx4anwDgtXajNzpcVOkDS0/qjM92/CkHtAi8iL+XD83MuHtE4PdmtAVHQOjCBHCXWk6GwwmxO3dxPJtZq+um5+JhaEiekMTdoFTbh2OUfY870oBSu/XgAJ3nUyw/7SQ==</D></RSAKeyValue>";
    string connectionString = "NccK+nelOKXcLSd5kckt1jKQFu7nos1EpS8LITzjB8dO1R4anPoAkQlq4GD/cIJKznUVByJkzf4y8LfnufEVlpz0WsdCkxVkL65QlHL/HZzWXAyR9OJ1/Fveeu26aEJ7yMqGnX0EDmIckL9iY+DHyhKB3duCTcUnKfb7JTUbBmcdV2mkNQUxFgA1w6pSIq7gE7AG5JKPzfKfIvp+DPn3rYTY/DarsmeCwHFnWgV0WTQNzzh6c5retiCYPHwKXd4EzliwIvjhhfBOzsbszWV53vcE3talArnepShDCs9jjk3EUK0ptMp2CXbe7IyNeAgjNO9wTnp1dHNlrI9YLVZvuw==";
    var bytesCypherText = Convert.FromBase64String(connectionString);
    var csp = new RSACryptoServiceProvider();
    var rsaParam = ParseXmlString(privateKey);
    csp.ImportParameters(rsaParam);
    var bytesPlainTextData = csp.Decrypt(bytesCypherText, false);
    // Note The Encoding must be the SAME as how you convert string to bytes : 
    //    Here we use Unicode
    var plainText =  System.Text.Encoding.Unicode.GetBytes("hello,world");
    var x = csp.Encrypt(plainText, false);
    var plainTextData = System.Text.Encoding.Unicode.GetString(bytesPlainTextData);
    Console.WriteLine(plainTextData);
}

这里的ParseXmlString(string xml)主要是copied from GitHub

public static RSAParameters ParseXmlString( string xml){
    RSAParameters parameters = new RSAParameters();
    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    xmlDoc.LoadXml(xml);
    if (! xmlDoc.DocumentElement.Name.Equals("RSAKeyValue")) {
        throw new Exception("Invalid XML RSA key.");
    }
    foreach (System.Xml.XmlNode node in xmlDoc.DocumentElement.ChildNodes)
    {
        switch (node.Name)
        {
            case "Modulus": parameters.Modulus = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
            case "Exponent": parameters.Exponent = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
            case "P": parameters.P = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
            case "Q": parameters.Q = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
            case "DP": parameters.DP = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
            case "DQ": parameters.DQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
            case "InverseQ": parameters.InverseQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
            case "D": parameters.D = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
        }
    }
    return parameters;
}

测试

测试以上代码的powershell:

$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider -ArgumentList 2048
# export private key to xml
$rsa.ToXmlString($true) | Out-File key.private.xml

# plain 
$p =[System.Text.Encoding]::Unicode.GetBytes( "hello,world"); 
# cipher (bytes)
$c = $rsa.Encrypt($p, $false)
# cipher (base64)
$ct = [Convert]::ToBase64String($c)

#decrypted (bytes)
$d = $rsa.Decrypt($c, $false);
[System.Text.Encoding]::Unicode.GetString($d);