5

我正在使用智能卡进行身份验证。

SecurityTokenService(身份验证服务)仅托管在我的机器上。智能卡有一个有效的证书,它的根证书也安装在我机器上的本地计算机存储中。

当我使用X509Certificate2.Verify方法验证服务中的证书时,它总是返回false.

有人可以帮我理解为什么 X509Certificate2.Verify() 方法总是返回 false 吗?

注意:我使用X509Chain并检查了所有标志 ( X509VerificationFlags.AllFlags)。当我构建 chanin 时,它true返回ChainStatusas RevocationStatusUnknown


编辑1:

如果我在 Windows 窗体应用程序中编写此代码,我观察到该X509Certificate2.Verify() 方法返回。truefalse仅在服务端代码中返回。为什么这样?奇怪但真实!

4

2 回答 2

2

X509VerificationFlags 值是抑制,因此指定X509VerificationFlags.AllFlags实际上可以防止 Build 在大多数情况下返回 false。

RevocationStatusUnknown回应似乎特别相关。无论它报告的哪个证书都无法验证为未被撤销。该Verify方法可以建模为

public bool Verify()
{
    using (X509Chain chain = new X509Chain())
    {
        // The defaults, but expressing it here for clarity
        chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
        chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
        chain.ChainPolicy.VerificationTime = DateTime.Now;
        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;

        return chain.Build(this);
    }
}

哪个,因为它没有断言X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknownX509VerificationFlags.IgnoreEndRevocationUnknown在请求 X509RevocationMode 以外的时候None失败。

首先,您应该确定链中的哪些证书(/正在)失败:

using (X509Chain chain = new X509Chain())
{
    // The defaults, but expressing it here for clarity
    chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
    chain.ChainPolicy.VerificationTime = DateTime.Now;

    chain.Build(cert);

    for (int i = 0; i < chain.ChainElements.Count; i++)
    {
        X509ChainElement element = chain.ChainElements[i];

        if (element.ChainElementStatus.Length != 0)
        {
            Console.WriteLine($"Error at depth {i}: {element.Certificate.Subject}");

            foreach (var status in element.ChainElementStatus)
            {
                Console.WriteLine($"  {status.Status}: {status.StatusInformation}}}");
            }
        }
    }
}

如果您在 Windows CertUI 中查看任何失败的证书(在资源管理器或证书 MMC 管理单元中双击 .cer),请查找名为“CRL 分发点”的字段。这些是将在运行时检索的 URL。也许您的系统有一个数据出口限制,不允许查询这些特定值。您始终可以尝试从您的 Web 服务发出 Web 请求,以查看它是否可以在没有位于证书子系统中的上下文的情况下获取 URL。

于 2016-07-06T16:21:32.483 回答
0

我认为,问题是由于我的组织中的代理服务器和一些安全设置造成的。我无法给出为什么它可以在 WinForm 客户端运行以及为什么不能从 IIS 下托管的代码中运行的正当理由。

但我想让读者知道的事实是,Verify()当我在我常用域之外的机器上运行的 IIS 中托管服务时,该方法也适用于服务器端代码!因此,您可以检查您的域/组织的防火墙设置是否妨碍您。

于 2012-04-30T12:49:06.367 回答