简体   繁体   English

如何正确使用X509Store?

[英]How to correctly use X509Store?

I've been using X509Store and his friends, X509Certificate2 and X509Certificate2Collection . 我一直在使用X509Store和他的朋友, X509Certificate2X509Certificate2Collection Everything was fine, but I've started to write tests for my code, and I've run into a problem. 一切都很好,但我已经开始为我的代码编写测试,我遇到了一个问题。 I generate a new test cert and install it to start each test, then remove the test cert at the end. 我生成一个新的测试证书并安装它以开始每个测试,然后在最后删除测试证书。 The test certificates are non-deterministically not valid, despite having creation dates a day in the past and expiry dates a day in the future. 尽管测试证书在过去的某一天有创建日期,而在将来的某一天有到期日期,但测试证书是非确定性无效的。

I've noticed that running a full GC and waiting for finalizers in TearDown fixes the tests. 我注意到运行完整的GC并在TearDown中等待终结器可以修复测试。

I've been digging into the reference source here. 我一直在挖掘参考资料。 It seems that X509Certificate2 needs to be disposed, otherwise operations that already returned success (like adding to a store) can have not been flushed to the actual store (this is a behaviour of the Windows API, see CertCloseStore CRYPT_E_PENDING_CLOSE result). 似乎需要处理X509Certificate2 ,否则已经返回成功的操作(如添加到商店)可能尚未刷新到实际存储(这是Windows API的行为,请参阅CertCloseStore CRYPT_E_PENDING_CLOSE结果)。

It further seems that X509Certificate2Collection is basically just a List<X509Certificate2> , so every time such a list of certs is created, every single instance needs to be disposed, such as reading the Certificates property on the store. 进一步看来, X509Certificate2Collection基本上只是一个List<X509Certificate2> ,因此每次创建这样的证书列表时,都需要处理每个实例,例如读取商店上的Certificates属性。

Furthermore, when the Find method is used, this involves creating a temporary store, adding the certs, and then reading the certs back out again from unmanaged code, creating a new collection of certs which also all need to be disposed. 此外,当使用Find方法时,这涉及创建临时存储,添加证书,然后从非托管代码中再次读取证书,创建一个新的证书集合,这些证书需要处理。

Is this really the correct way to use the X509Store ? 这真的是使用X509Store的正确方法吗? It seems to be unbelievable that the .NET API would be so tremendously unsafe and difficult to use correctly with silent failures and completely undocumented failure modes everywhere. 似乎令人难以置信的是,.NET API会如此极不安全,并且难以正确使用无声故障以及无处不在的无故障故障模式。 Am I just missing something obvious or should these classes all be avoided? 我只是遗漏了一些明显的东西,还是应该避免这些课程?

What undocumented failure modes? 什么无证失效模式? You're supposed to dispose every single disposable object you own. 你应该处置你拥有的每一个一次性物品。 This applies especially when you know you're dealing with native code. 这尤其适用于您知道自己正在处理本机代码的情况。 This is nothing specific to the certificate interfaces - files work the same way, database transactions work the same way, sockets work the same way. 这与证书接口无关 - 文件的工作方式相同,数据库事务的工作方式相同,套接字的工作方式相同。 That's why the IDisposable interface exists in the first place - it's the common interface saying "call me when you're done". 这就是为什么IDisposable接口首先存在的原因 - 这是常见的界面,“当你完成时给我打电话”。 Did you stop using file I/O when you realized you're required to close the file? 当您意识到需要关闭文件时,您是否停止使用文件I / O? Or haven't you noticed that it's required yet? 或者你没有注意到它是必需的吗?

The whole cryptography module that deals with SChannel is little more than a thin wrapper on top of SChannel. 处理SChannel的整个加密模块只不过是SChannel上的一个薄包装器。 That is, almost every single thing you do is native interop, managed wrappers over native objects etc. 也就是说,您所做的几乎所有事情都是本机互操作,本机对象的托管包装等。

But it doesn't matter what the exact problem is. 但问题究竟是什么并不重要。 The key point is still that you're supposed to dispose disposables, always. 关键是你应该永远处理一次性用品。 Just because things seem to kind of work even if you don't doesn't mean it's fine to omit disposing objects. 只是因为事情似乎有点工作,即使你不这样做也不意味着省略处理对象是件好事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM