【发布时间】:2018-01-19 05:00:51
【问题描述】:
我正在使用以下代码仅获取机器上的有效(按时间)证书:
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
var storeCol = store.Certificates;
store.Close();
var notExpiredCol = storeCol.Find(X509FindType.FindByTimeValid, DateTime.Now, true);
在我的机器上它运行良好。但是,在另一台具有相同配置(Windows 10、Visual Studio Community 2017 并安装完全相同的证书)的机器上,它什么也不返回。
来自商店的原始集合,没有过滤器,有证书。如果我们查看 Internet Explorer 下的证书,证书就在那里。如果我们在带有证书管理单元的 MMC 下查看,证书就在那里。我们尝试在当前用户和本地机器下安装证书,代码是从当前用户获取证书集合。
我刚刚尝试使用 FindByTimeExpired 和 FindByTimeNotYetValid 条件,结果相同,都返回一个空集合:
var expiredCol = storeCol.Find(X509FindType.FindByTimeExpired, DateTime.Now, true);
var notYetValidCol = storeCol.Find(X509FindType.FindByTimeNotYetValid, DateTime.Now, true);
有没有人知道发生了什么或者我们可以检查什么来解决问题?
顺便问一下,validOnly 参数在 X509Certificate2Collection.Find() 方法上的具体作用是什么?如果我在其上使用值 false,该方法将返回集合上的证书。
【问题讨论】:
-
validOnly将导致X509Store.Find函数在它找到的任何证书上调用Verify。在您的情况下,证书很可能在另一台机器上不受信任。 -
就是这样,柯克,你已经搞定了,谢谢!关于 X509Certificate2Collection.Find() 方法的 Microsoft 文档应该提到
validOnly参数的一点特殊性。 -
我查看了该函数的 Mono 源代码并在那里找到了它的用法:github.com/mono/mono/blob/master/mcs/class/System/…。
-
但是(在 .NET 框架的 Windows 实现的源代码上)找到答案有点复杂。
X509Certificate2Collection.Find()方法调用FindCertInStore()函数,调用FindByCert()函数,最后调用X509Utils.VerifyCertificate()。但是X509Utils 是一个内部类……在 Mono 源代码上,更容易理解发生了什么。再次感谢柯克。
标签: c# .net certificate x509certificate2