RSACryptoServiceProvider KeyContainer似乎超时了吗?

时间:2010-08-30 23:38:00

标签: c# rsacryptoserviceprovider

我正在使用像这样的RSACryptoServiceProvider ......

 private byte[] RSAEncrypt(byte[] DataToEncrypt, string ContainerName, bool DoOAEPPadding)
    {
        try
        {
            byte[] encryptedData;

            // Create a new instance of CspParameters.  Pass
            // 13 to specify a DSA container or 1 to specify
            // an RSA container.  The default is 1.
            CspParameters cspParams = new CspParameters();

            // Specify the container name using the passed variable.
            cspParams.KeyContainerName = ContainerName;

            cspParams.Flags = CspProviderFlags.UseDefaultKeyContainer;

            //Create a new instance of RSACryptoServiceProvider.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cspParams))
            {
                //Encrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  

                encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
            }
            return encryptedData;
        }
        //Catch and display a CryptographicException  
        //to the console.
        catch (CryptographicException ex)
        {
            sl.Write(ex, MessageType.Error);
            throw;                
        }
    }

然后,在关闭我的Outlook插件Windows窗体应用程序并将其重新打开之后,我尝试解密数据,这就是使用此代码的方法。解密代码看起来像这样......

private byte[] RSAEncrypt(byte[] DataToEncrypt, string ContainerName, bool DoOAEPPadding)
    {
        try
        {
            byte[] encryptedData;

            // Create a new instance of CspParameters.  Pass
            // 13 to specify a DSA container or 1 to specify
            // an RSA container.  The default is 1.
            CspParameters cspParams = new CspParameters();

            // Specify the container name using the passed variable.
            cspParams.KeyContainerName = ContainerName;

            cspParams.Flags = CspProviderFlags.UseDefaultKeyContainer;

            //Create a new instance of RSACryptoServiceProvider.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cspParams))
            {
                //Encrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  

                encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
            }
            return encryptedData;
        }
        //Catch and display a CryptographicException  
        //to the console.
        catch (CryptographicException ex)
        {
            sl.Write(ex, MessageType.Error);
            throw;                
        }
    }    

效果很好,直到出现我无法指责的事情。我不知道它是否像日期变化或是什么。会发生什么事情,我试图解密数据,我得到一个“坏数据”错误。现在,它再次运行一段时间,或关闭应用程序,或用户注销。我只是不知道,也无法确定是什么原因造成的。当我吹走来自文本文件的加密数据并重新创建并解密它的那一刻我没有问题。即使我在加密/保存到文件和从文件/解密读取之间重新启动应用程序它也会很有效!有些事情发生了,我只是不太了解KeyContainers,以了解什么可能使CspParameters过期是我最好的猜测?

3 个答案:

答案 0 :(得分:0)

如果你真的陷入困境,你可以尝试使用充气城堡加密库:

http://www.bouncycastle.org/csharp/

答案 1 :(得分:0)

我最终使用了CspParameters标志,而不是使用Users KeyContainer商店,而是使用了Machine KeyContainer商店。

答案 2 :(得分:0)

是的,如果你设置: cspParams.Flags = CspProviderFlags.UseDefaultKeyContainer;

然后密钥容器存储在用户的密钥容器存储中,然后以另一个用户身份登录并使用RSA为您提供完全不同的KeyContainer存储。

使用此代替: cspParams.Flags = CspProviderFlags.UseMachineKeyStore = true;

将使用本地计算机的KeyContainer存储,它是计算机的全局存储,并且将为您提供相同的KeyContainer存储,无论哪个用户登录。但是,这仅适用于该Windows安装。在不同的Windows安装或机器下运行程序将为您提供不同的KeyContainer存储。如果您希望在多台计算机上解密相同的数据,则需要将密钥保存到硬盘驱动器上的文件中。将密钥保留为纯文本文件存在巨大的安全风险,因此请在将密钥保存到文件之前加密密钥,或者将其放入受密码保护的.rar文件或其他内容。

如果您仍有问题,请尝试设置: RSA.PersistKeyInCsp = true;

这将确保您的密钥保留在KeyContainer商店中。如果使用CspParameters构造函数,则在KeyContainer中保留文件应该是默认行为,如:

CspParameters cspParams = new CspParameters();

用微软自己的话来说: “这种形式的CspParameters将ProviderType字段初始化为值24,指定PROV_RSA_AES提供程序。” 资料来源:http://msdn.microsoft.com/en-us/library/xw9ywed4.aspx

所以你的代码中的评论不正确,我会误导你。我建议你纠正它们。

我不确定其他ProviderTypes及其在KeyContainer商店中保留密钥的默认设置,因此如果您仍然遇到问题,可能需要将PersistKeyInCsp设置为TRUE。

希望这有帮助。

~Adam WhiteHat();