使用 RSACryptoServiceProvider 生成 RSA 密钥时出现持久性错误

Persistence error when generating RSA key using RSACryptoServiceProvider

我在多次调用 RSACryptoServiceProvider 以创建 private/public 密钥对时遇到奇怪的错误问题:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            CreateKey();
        }
        catch (Exception e)
        {
            Console.WriteLine("First failure:"+ e);
        }

        try
        {
            CreateKey();
        }
        catch (Exception e)
        {
            Console.WriteLine("Second failure:" + e);
        }
    }

    private static void CreateKey()
    {
        var cp = new CspParameters
        {
            KeyContainerName = "ContainerKey.1"
        };
        using (var rsa = new RSACryptoServiceProvider(cp) { PersistKeyInCsp = false })
        {
            Console.WriteLine(rsa.ToXmlString(true));
            Console.WriteLine(rsa.ToXmlString(false));
            rsa.Clear();
        }
    }
}

执行以上代码的输出是(省略我的):

<RSAKeyValue>[Private key content omitted]</RSAKeyValue>
<RSAKeyValue>[Public key content omitted]</RSAKeyValue>
Second failure:System.Security.Cryptography.CryptographicException: Keyset as registered is invalid.

   at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
   at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
   at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
   at RsaTest.Program.CreateKey() in C:\Users\RF185104\source\repos\RsaTest\RsaTest\Program.cs:line 39
   at RsaTest.Program.Main(String[] args) in C:\Users\RF185104\source\repos\RsaTest\RsaTest\Program.cs:line 25

运行上面的代码,第一次调用CreateKey正常,但是第二次调用失败。当再次重新 运行 代码时,现在甚至第一次失败,这意味着某处存在某些东西。但这不应该发生,因为将 PersistKeyInCsp 设置为 false 应该会阻止密钥的持久性。更改 KeyContainerName 会导致调用再次运行,但只会运行一次。下一次调用也会失败。

我想我对RSACryptoServiceProvider的工作原理有很大的误解,因为我不知道上面的错误是怎么来的。

此代码的主要目的是创建一个 RSA 密钥对而不将其保存到本地存储,因此同一用户上的其他应用程序 运行 无法访问它。

运行 Windows 10,.NET Framework 4.7.2,在调试和发布中都会出现。

我们在生产中遇到了同样的问题。结果是 McAfee AntiVirus 导致了这个问题。它将此消息记录到应用程序事件日志

username ran process name, which tried to access ...\APPDATA\ROAMING\MICROSOFT\CRYPTO\RSA\ Windows SID \ randomish folder name , violating the rule "Malware Behavior: Windows EFS abuse", and was blocked. For information about how to respond to this event, see KB85494.