我应该处理 X509Certificate2 吗?

Should I dispose of X509Certificate2?

我正在使用 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

Starting with the .NET Framework 4.6, this type implements the IDisposable interface. When you have finished using the type, you should dispose of it either directly or indirectly.

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

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