首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >store.Open和store.Certificates.Find方法对X509Store性能的影响

store.Open和store.Certificates.Find方法对X509Store性能的影响
EN

Stack Overflow用户
提问于 2015-11-05 20:25:48
回答 1查看 1.4K关注 0票数 2
代码语言:javascript
复制
private static X509Certificate2 FindCertificate(string certificateSubject)
{
    const StoreName StoreName = StoreName.My;
    const StoreLocation StoreLocation = StoreLocation.LocalMachine;

    var store = new X509Store(StoreName, StoreLocation); 
    try
    {
        store.Open(OpenFlags.ReadOnly);

        // Find with the FindBySubjectName does fetch all the certs partially matching the subject name.
        // Hence, further filter for the certs that match the exact subject name.
        List<X509Certificate2> clientCertificates =
            store.Certificates.Find(X509FindType.FindBySubjectName, certificateSubject, validOnly: true)
                .Cast<X509Certificate2>()
                .Where(c => string.Equals(
                    c.Subject.Split(',').First().Trim(),
                    string.Concat("CN=", certificateSubject).Trim(),
                    StringComparison.OrdinalIgnoreCase)).ToList();

        if (!clientCertificates.Any())
        {
            throw new InvalidDataException(
                string.Format(CultureInfo.InvariantCulture, "Certificate {0} not found in the store {1}.", certificateSubject, StoreLocation.LocalMachine));
        }

        X509Certificate2 result = null;
        foreach (X509Certificate2 cert in clientCertificates)
        {
            DateTime now = DateTime.Now;
            DateTime effectiveDate = DateTime.Parse(cert.GetEffectiveDateString(), CultureInfo.CurrentCulture);
            DateTime expirationDate = DateTime.Parse(cert.GetExpirationDateString(), CultureInfo.CurrentCulture);
            if (effectiveDate <= now && expirationDate.Subtract(now) >= TimeSpan.FromDays(1))
            {
                result = cert;
                break;
            }
        }

        return result;
    }
    finally
    {
        store.Close();
    }
}

我的库中有这段代码,每次创建新请求时,它都会调用此方法。所以,基本上,每秒的请求是1000,那么它将被调用1000次。当我使用PerfView工具时,我注意到35%的CPU是通过这种方法使用的。最大的罪魁祸首是store.Open和store.Certificates.Find方法。

其他人在代码中发现了类似的问题。此外,如果您可以共享您做了什么来解决由于此而造成的性能影响。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-05 21:42:28

只要目标系统没有安装大量证书,就可以跳过对X509Store的.Find()方法的调用。根据我的经验,它的性能不太好,之后您已经对目标subjectName进行了必要的筛选。

另外,不要在X509Certificate2集合中循环两次!如果您只需要满足所有条件的第一个匹配证书,可以将事情简化为一个LINQ语句,如下所示:

代码语言:javascript
复制
X509Certificate2 cert =
    store.Certificates.Cast<X509Certificate2>()
        .FirstOrDefault(xc =>
            xc.Subject.Equals("CN=" + certificateSubject, StringComparison.OrdinalIgnoreCase)
            && xc.NotAfter >= DateTime.Now.AddDays(-1)
            && xc.NotBefore <= DateTime.Now);

(请注意,根据您的用法和证书,您可能需要或不需要修改上面的内容,以便像原来的代码那样以逗号分隔主题)。

最后,如前所述,如果您的目标计算机没有安装大量证书,则可以通过调用store.Certificates.Cast<X509Certificate2>().ToList()缓存整个证书列表,或者如果您搜索的subjectNames数量有限,则使用从subjectName派生的密钥缓存此方法的结果并基于NotAfter属性进行过期可能更有效。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33554122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档