1

我有这个函数用来解密在我的开发机器上运行良好的值。但是当在另一台服务器上运行时 - 给出了这个确切的错误消息:

该系统找不到指定的文件。

这是功能:

 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 上得到了答案,这种加密/解密方法完全适用于字符串,无需导入/导出密钥。

所以....现在我缺少一个密钥文件?这怎么可能我什至没有创建密钥文件。

4

5 回答 5

2

请注意,您没有将key参数用作密码,而是用作容器的名称。这依赖于较早存储密钥的加密函数。不适合跨计算机传输加密数据。除非您也转移密钥。

于 2009-10-01T17:02:23.557 回答
2

如果您需要将密钥从一台机器复制到另一台机器,则必须将其从密钥容器中导出。我们发现rsaCryptoServiceProvider.ImportCspBlobExportCspBlob方法可以很好地解决这个问题;你得到一个单字节数组,然后你可以Convert.ToBase64StringConvert.FromBase64String.

当然,它必须是一个可导出的密钥(或者更好的是,只导出公钥,这是 PKC 的方式,因此一端有私钥,另一端只有公钥)。不可导出的密钥只能导出其公钥。一旦系统正常工作,您可以创建一个新的不可导出密钥,您需要将私钥驻留在其中,然后导出公钥以将其传输到需要加密的任何其他地方给该单个收件人。

此外,您需要确保Dispose在完成后向加密提供者提供服务(显然Clear()还不够好)。using如果您在一个本地范围内使用它,或者您可以在您的finally块中使用它,最好使用一个语句来执行此操作。请注意,它是IDisposable显式实现的,因此您必须将其转换为IDisposable有些笨拙才能在单独的语句中执行。using语句处理转换本身,因此更容易。

于 2009-10-01T17:10:03.690 回答
1

使用 Sysinternals.com 的 FileMon 来查看它在寻找什么文件?

我的猜测是 cspp.KeyContainerName = key; 是相关行。

于 2009-10-01T16:58:57.910 回答
0

那么,您是否将密钥安装在key服务器上以加密提供程序命名的容器中?请参阅如何:使用 X.509 证书管理工具

顺便说一句,如果您能够在您的机器上解密一些应该是服务器上的私钥的东西,那么密钥已经被泄露。你应该尽快更换钥匙。

更新

RSA 加密基于非对称密钥。你用公钥加密,目的地用私钥解密。密钥是预先提供的,您的目的地生成或获取密钥对,并将私有部分保留给自己,并为他人宣传公共部分。通常将密钥打包为 X509 证书,因为这利用了围绕证书的整个信任基础架构(签名、受信任的权威机构、证书用途等)。在这种情况下,消息的目的地必须从受信任的机构(即 Verisign)等处请求用于加密目的的证书。或者使用自签名证书(makecert.exe)并通过一些带外方法(即. 验证证书哈希或颁发者名称/序列号的电话)。

RSa 密码学远非“只是字符串”。更接近“只是字符串”的是对称密钥加密(AES、DES、XDES、RC4),您的应用程序有一个用于加密和解密的密钥。

现在,除非您真的知道自己在做什么,否则请避开密码学,使用现成的协议,如SSL/TLS(在线)或S-MIME(离线)。更好的是,使用一些框架工具,如CryptoStreamProtectedData。不要根据从未见过的人的新闻组建议创建另一个伪加密......

于 2009-10-01T17:03:17.120 回答
0

一个问题可能是 RSA 对象试图在用户配置文件中创建 CryptoContainer。
你可以尝试添加这个:

rsa.UseMachineKeyStore = true;
于 2009-10-01T17:06:25.773 回答