我有这个功能,我用来解密我的开发机器上工作正常的值。但是当在另一台服务器上的生产中运行时 - 给出这个确切的错误消息:
系统找不到指定的文件。
这是功能:
public static string Decrypt(string stringToDecrypt, string key)
{
string result = null;
if (string.IsNullOrEmpty(stringToDecrypt))
{
throw new ArgumentException("An empty string value cannot be encrypted.");
}
if (string.IsNullOrEmpty(key))
{
throw new ArgumentException("Cannot decrypt using an empty key. Please supply a decryption key.");
}
try
{
System.Security.Cryptography.CspParameters cspp = new System.Security.Cryptography.CspParameters();
cspp.KeyContainerName = key;
System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(cspp);
rsa.PersistKeyInCsp = true;
string[] decryptArray = stringToDecrypt.Split(new string[] { "-" }, StringSplitOptions.None);
byte[] decryptByteArray = Array.ConvertAll<string, byte>(decryptArray, (s => Convert.ToByte(byte.Parse(s, System.Globalization.NumberStyles.HexNumber))));
byte[] bytes = rsa.Decrypt(decryptByteArray, true);
result = System.Text.UTF8Encoding.UTF8.GetString(bytes);
}
finally
{
// no need for further processing
}
return result;
}
更新
伙计们,我最初选择了这条路线,因为经过数小时和数小时的搜索后,我得到了stackoverflow的答案,这种加密/解密方法完全适用于字符串,无需导入/导出密钥。
所以....现在我错过了一个密钥文件?这怎么可能我甚至都没有创建密钥文件。
答案 0 :(得分:2)
请注意,您没有将key
参数用作密码,而是用作容器的名称。这依赖于先前存储密钥的加密功能。不适合跨计算机传输加密数据。除非你转移钥匙。
答案 1 :(得分:2)
如果您需要将密钥从一台计算机复制到另一台计算机,则必须从密钥容器中导出密钥。我们发现rsaCryptoServiceProvider.ImportCspBlob
和ExportCspBlob
方法适用于此;你得到一个单字节数组,然后你可以Convert.ToBase64String
和Convert.FromBase64String
。
当然,它必须是一个可导出的密钥(或者更好的是,只导出公钥,这是PKC的意图,所以一端有私钥,另一端只有公钥)。不可导出的密钥只能导出其公钥。一旦您使系统工作,您可以创建一个新的不可导出密钥,您需要私钥驻留,并导出公钥以将其传输到其他需要加密到该单个收件人的地方。
此外,您需要确保Dispose
加密提供程序完成后(显然Clear()
不够好)。如果您在一个本地范围内使用它,则可以使用using
语句来执行此操作,或者您可以在finally
块中执行此操作。请注意,它明确地实现了IDisposable
,因此您必须将它强制转换为IDisposable
,以便在单独的语句中执行它。 using
语句处理转换本身,因此更容易。
答案 2 :(得分:1)
使用Sysinternals.com的FileMon查看它正在寻找的文件?
我的猜测是cspp.KeyContainerName = key;是相关的。
答案 3 :(得分:0)
那么,您是否在服务器上的加密提供程序中将密钥安装在名为key
的容器中?请参阅How to: Use the X.509 Certificate Management Tools。
更新
之后RSA密码术基于不对称密钥。您使用公钥加密,目标使用私钥解密。密钥是预先设置的,您生成或获取密钥对的目的地,并将私有部分保留给自己并为其他人公开公共部分。通常,密钥被打包为X509证书,因为它利用了围绕证书的整个信任基础设施(签名,可信管理机构,证书目的等)。在这种情况下,消息的目的地必须从受信任的机构(即Verisign)等请求用于加密目的的证书。或者使用自签名证书(makecert.exe)并通过一些带外方法建立信任(即。一个电话调用验证证书哈希或IssuerName / SerialNumber)。
RSa密码学非常远离“只是字符串”。更接近“只是字符串”的是对称密钥加密(AES,DES,XDES,RC4),其中您的应用程序具有用于加密和解密的密钥。
现在,除非您确实知道正在做什么,否则请避开加密,使用现成的协议,如SSL/TLS(在线)或S-MIME(离线) )。更好的是,使用一些框架工具,如CryptoStream或ProtectedData。不要根据你从未见过的人的新闻组建议创建另一个伪加密......
答案 4 :(得分:0)
问题可能是RSA对象尝试在用户配置文件中创建CryptoContainer 您可以尝试添加此内容:
rsa.UseMachineKeyStore = true;