C# RSACryptoServiceProvider密钥容器是否超时?

C# RSACryptoServiceProvider密钥容器是否超时?,c#,rsacryptoserviceprovider,C#,Rsacryptoserviceprovider,我正在像这样使用RSACryptServiceProvider private byte[] RSAEncrypt(byte[] DataToEncrypt, string ContainerName, bool DoOAEPPadding) { try { byte[] encryptedData; // Create a new instance of CspParameters. Pass

我正在像这样使用RSACryptServiceProvider

 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;                
        }
    }
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;                
        }
    }
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过期,这是我最好的猜测?

如果您真的陷入困境,您可以尝试使用bouncy castle加密库:


我最终使用了CspParameters标志,而不是用户密钥容器存储,我使用了机器密钥容器存储。

是,如果您设置: cspParams.Flags=CspProviderFlags.UseDefaultKeyContainer

然后,密钥容器存储在用户的密钥容器存储中,然后按照其他用户的意愿登录,并使用RSA向您展示一个完全不同的密钥容器存储

使用此选项: cspParams.Flags=CspProviderFlags.UseMachineKeyStore=true

将使用本地计算机的KeyContainer存储,这是该计算机的全局存储,并将为您提供相同的KeyContainer存储,而不管用户是否登录。但是,这仅适用于该windows安装。在不同的windows安装或计算机下运行程序将为您提供不同的KeyContainer存储。如果希望在多台计算机上解密相同的数据,则需要将密钥保存到硬盘上的文件中。将密钥持久化到纯文本文件是一个巨大的安全风险,因此请在将密钥持久化到文件之前对其进行加密,或者将其放入受密码保护的.rar文件或其他文件中

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

这将确保您的密钥保存在KeyContainer存储中。如果使用CspParameters构造函数,则在KeyContainer中持久化文件应该是默认行为,例如:

CspParameters cspParams=新CspParameters()

用微软自己的话说: 此形式的CSP参数将ProviderType字段初始化为值24,该值指定PROV_RSA_AES提供程序 资料来源:

因此,您在代码中的注释是不正确的,我的注释可能会误导您。我建议你改正它们

我不确定其他ProviderType及其关于在KeyContainer存储中持久化密钥的默认设置,因此如果您仍然存在问题,可能需要将PersistKeyInCsp设置为TRUE

希望这有帮助

~Adam WhiteHat()