无法在 .Net Core 中使用 RSA 私钥解密连接字符串
Posted
技术标签:
【中文标题】无法在 .Net Core 中使用 RSA 私钥解密连接字符串【英文标题】:Unable to decrypt connection string using RSA private key in .Net Core 【发布时间】:2020-01-23 06:17:03 【问题描述】:我能够使用带有 Encoding.UTF8 和 RSACryptoServiceProvider() 的 RSA 公钥加密连接字符串。
但是当我试图解密它时,我正面临着
"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 框架,我遇到了很多 *** 线程,并且知道我们可以通过配置生成器来完成它,但我很难找到如何去做。
我是.Net平台的初学者,所以请验证以上细节并帮助我获取解密文本。
【问题讨论】:
为什么要对连接字符串进行 RSA 加密?这有点令人担忧。 需求从何而来? (你没有提到有这样的要求。) 这是我们项目计划的一部分,我们正在使用 RSA 这里应该使用 RSA 来完成什么? 为了完整起见:FromXmlString
/ToXmlString
从 .NET Core 3.0 开始支持 (3.0, 3.1),here。在PlatformNotSupportedException
下方抛出。 IE。 csp.FromXmlString(privateKey);
也可以解决问题(假设对应的 .NET Core 版本)。
【参考方案1】:
您似乎正在尝试使用 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);
【讨论】:
以上是关于无法在 .Net Core 中使用 RSA 私钥解密连接字符串的主要内容,如果未能解决你的问题,请参考以下文章