X509Certificate2.Verify()方法始终为有效证书返回false

时间:2012-04-13 08:00:14

标签: c# x509certificate2

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

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

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

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

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


编辑1:

如果我在windows窗体应用程序中编写此代码,我发现X509Certificate2.Verify()方法返回true。它仅在服务端代码中返回false。为什么这样?奇怪但真实!

2 个答案:

答案 0 :(得分: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.IgnoreCertificateAuthorityRevocationUnknown以外的X509RevocationMode时未声明X509VerificationFlags.IgnoreEndRevocationUnknownNone,因此失败。

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

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。

答案 1 :(得分:0)

我认为,问题是由于我的组织中的代理服务器和一些安全设置。我无法说明为什么它可以从WinForm客户端工作,为什么不能从IIS下托管的代码。

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