我应该处理 X509Certificate2 吗?
Posted
技术标签:
【中文标题】我应该处理 X509Certificate2 吗?【英文标题】:Should I dispose of 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 接口。当您使用完该类型后,您应该直接或间接地处理它。
【问题讨论】:
【参考方案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
我可以处理证书。我想知道我是否正确使用证书,也许还有其他方法。以上是关于我应该处理 X509Certificate2 吗?的主要内容,如果未能解决你的问题,请参考以下文章
我应该处理 WSASend() 可能不会发送所有数据的事实吗?
第二次创建peerconeection WebRTC时出现问题(轨道已经存在一个发件人。),我应该处理任何想法