【问题标题】:Should I dispose of X509Certificate2?我应该处理 X509Certificate2 吗?
【发布时间】:2019-10-13 16:48:41
【问题描述】:

我正在使用 IdentityServer4,我想从文件中加载签名证书。例如,

var certificate = new X509Certificate2(
        path, 
        password, 
        X509KeyStorageFlags.EphemeralKeySet);

services.AddIdentityServer()
        .AddSigningCredential(certificate)
...
certificate.Dispose();

当我从 IdentityServer 请求令牌时,上面的代码将不起作用。但如果我删除certificate.Dispose();,它将起作用。

我还尝试了另一种选择。我从证书的私钥创建了RsaSecurityKey 并将其用于添加签名凭据。在这种情况下,处理不会破坏任何东西。

var rsk = new RsaSecurityKey(certificate.GetRSAPrivateKey()))

services.AddIdentityServer()
        .AddSigningCredential(rsk)
...
certificate.Dispose()

所以我的问题更笼统。我应该处置从现有证书创建的X509Certificate2 对象吗?


来自Microsoft Docs

从 .NET Framework 4.6 开始,此类型实现 IDisposable 接口。当您使用完该类型后,您应该直接或间接地处理它。

【问题讨论】:

    标签: c# identityserver4 idisposable x509certificate2 asp.net-core-2.2


    【解决方案1】:

    通过查看.NET Core源码,X509Certificate2及其基类X509Certificate使用类CertificatePal来处理证书。 CertificatePal 类支持从各种来源创建类对象:blob、文件、证书存储。它在创建对象时调用 Windows CryptoAPI 来获取证书的句柄。因此,在使用对象之后,有必要释放句柄指向的资源。好消息是,句柄存储在 SafeCertContextHandle 对象中,保证在垃圾收集器收集 X509Certificate2 对象并调用完对象。我的理解是,我们不需要手动调用Dispose方法。

    【讨论】:

    • 我昨晚阅读了下面的博客文章,它也让我研究了这个问题:snede.net/the-most-dangerous-constructor-in-net 我的代码正在使用构造函数,从不释放或调用 Reset 方法。在我的本地机器、开发和登台服务器上,在过去一年中,我在 Microsoft 用来存储 x509Certficate2 文件的各种文件夹中没有看到两个以上的文件,所以我猜垃圾收集正在清理它,就像你说的那样.
    【解决方案2】:

    不,您不应该在应用程序运行时释放证书对象,因为当请求时,IdentityServer 将尝试使用已释放的证书对象并且会失败。

    【讨论】:

    • 是的,在第一种情况下这是合理的。但是使用RsaSecurityKey 我可以处理证书。我想知道我是否正确使用证书,也许还有其他方法。
    猜你喜欢
    • 2016-09-05
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 2011-02-19
    • 2010-09-30
    • 2019-01-15
    • 2017-04-16
    • 2013-01-23
    相关资源
    最近更新 更多