我应该处理 X509Certificate2 吗?

Myk*_*kun 13 c# idisposable x509certificate2 identityserver4 asp.net-core-2.2

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

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

services.AddIdentityServer()
        .AddSigningCredential(certificate)
...
certificate.Dispose();
Run Code Online (Sandbox Code Playgroud)

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

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

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

services.AddIdentityServer()
        .AddSigningCredential(rsk)
...
certificate.Dispose()
Run Code Online (Sandbox Code Playgroud)

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


来自微软文档

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

rob*_*fan 9

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

  • 我昨晚读了下面的博客文章,它也让我研究了这个问题:https://snede.net/the-most-dangerous-constructor-in-net/ 我的代码正在使用构造函数,从不处理或调用“重置”方法。在我的本地计算机、开发和临时服务器上,过去一年中,在 Microsoft 用于存储“x509Certficate2”文件的各个文件夹中,我没有看到超过两个文件,所以我猜垃圾收集正在清理它,正如您所说。 (4认同)

Cry*_*t32 5

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