C# 如何检查X509证书是否有;“扩展验证”;打开了吗?

C# 如何检查X509证书是否有;“扩展验证”;打开了吗?,c#,ssl,x509certificate,C#,Ssl,X509certificate,我正在努力寻找一种可靠的方法,从我的C#(.Net 4.0)应用程序中检查X509Certificate(或X509Certificate2)是否设置了“扩展验证”(EV)标志。有人知道最好的方法吗?您可以检查X509证书是否包含这些方法之一。此外,您还可以查看Chromium的源代码以获得已实现OID的列表。你可以找到来源。如果你想坚持使用Firefox,你可以抓取它的实现 我现在更新了我的源代码并进行了测试。我编写了一个小方法,根据维基百科/Chromium中的OId列表验证X509Cert

我正在努力寻找一种可靠的方法,从我的C#(.Net 4.0)应用程序中检查X509Certificate(或X509Certificate2)是否设置了“扩展验证”(EV)标志。有人知道最好的方法吗?

您可以检查
X509证书是否包含这些方法之一。此外,您还可以查看Chromium的源代码以获得已实现OID的列表。你可以找到来源。如果你想坚持使用Firefox,你可以抓取它的实现

我现在更新了我的源代码并进行了测试。我编写了一个小方法,根据维基百科/Chromium中的OId列表验证
X509Certificate2
。在这个方法中,我使用的是维基百科列表,最好使用Chromium列表


OId是如何保存的? 每个
CA
都有一个或多个objectID
OId
s。它们不会像您可能猜到的那样保存为扩展,而是保存为策略扩展中的条目。要获得确切的扩展名,建议使用
策略扩展名本身的Oid,而不是使用友好的名称。策略扩展的OId是
2.5.29.32

提取信息 要获取策略扩展的内部内容,我们可以使用
System.Security.Cryptography.AsnEncodedData
将其转换为可读的
字符串。字符串本身包含我们需要与
字符串[]
匹配的策略,以确保它是否包含
EV证书的OID之一

来源
如果有人知道实现这一目标的更好方法,请告诉我们。

我想我会发布一个更完整的答案,尽管这个问题已经很老了。为了使这个答案完整,我不会背弃现有答案

<>一个EV证书有几个检查需要通过,以便浏览器考虑证书是EV。< /P>
  • 证书具有已知为EV策略的策略标识符
  • 证书的根目录的指纹与固定的策略标识符匹配
  • 证书必须通过联机吊销检查
  • 如果证书的notBefore(发布日期)在2015年1月1日之后,则证书必须支持证书透明度
  • 证书必须由受信任的根用户颁发
  • 如果存在多个信任路径,则所有链都有效
  • 让我们逐一剖析一下

    策略标识符 证书具有称为策略标识符的扩展。可从
    X509Certificate2.Extensions
    属性访问扩展。策略标识符扩展的对象标识符(“OID”)为
    2.5.29.32
    。因此,我们可以使用如下方式获得原始扩展:

    var extension = certificate.Extensions["2.5.29.32"]
    
    {{0x06, 0x3e, 0x4a, 0xfa, 0xc4, 0x91, 0xdf, 0xd3, 0x32, 0xf3, 0x08,
          0x9b, 0x85, 0x42, 0xe9, 0x46, 0x17, 0xd8, 0x93, 0xd7, 0xfe, 0x94,
          0x4e, 0x10, 0xa7, 0x93, 0x7e, 0xe2, 0x9d, 0x96, 0x93, 0xc0}},
        {
            // AC Camerfirma uses the last two arcs to track how the private key
            // is managed - the effective verification policy is the same.
            "1.3.6.1.4.1.17326.10.14.2.1.2", "1.3.6.1.4.1.17326.10.14.2.2.2",
        }
    
    如果返回null,表示根本没有任何策略,您可以立即假定这不是EV证书

    更可能的情况是,证书具有某种策略。在这种情况下,您需要对数据进行解码。该属性将在原始ASN.1中提供给您,我们需要对其进行解释

    不幸的是,目前在.NET中没有任何东西可以做到开箱即用。但是,如果使用平台调用,则可以执行此操作。关于如何调用此函数的详细信息我将略去,但有大量信息可以说明如何调用此函数。您需要将lpszStructType参数设置为
    (IntPtr)16
    值来调用它。这将返回一个结构,其中包含一个计数和指向
    CERT\u POLICY\u INFO
    结构数组的指针。此结构上有一个名为
    pszPolicyIdentifier
    的字段。我们感兴趣的就是这个政策

    每个证书颁发机构都有一个或多个OID,用于将证书作为EV。每个CA在其策略页面上记录它们。然而,获取最新列表的最佳位置可能是

    如果证书的策略与这些OID中的一个相匹配,那么我们可以继续进行下一个检查

    根指纹 如果您查看上面链接中的Chromium源,您将看到除了策略标识符之外,它还保留根的SHA256指纹

    这是因为除了具有适当OID的证书外,它还必须由指纹匹配的CA颁发。在铬源中,我们看到如下情况:

    var extension = certificate.Extensions["2.5.29.32"]
    
    {{0x06, 0x3e, 0x4a, 0xfa, 0xc4, 0x91, 0xdf, 0xd3, 0x32, 0xf3, 0x08,
          0x9b, 0x85, 0x42, 0xe9, 0x46, 0x17, 0xd8, 0x93, 0xd7, 0xfe, 0x94,
          0x4e, 0x10, 0xa7, 0x93, 0x7e, 0xe2, 0x9d, 0x96, 0x93, 0xc0}},
        {
            // AC Camerfirma uses the last two arcs to track how the private key
            // is managed - the effective verification policy is the same.
            "1.3.6.1.4.1.17326.10.14.2.1.2", "1.3.6.1.4.1.17326.10.14.2.2.2",
        }
    
    因此证书必须具有“1.3.6.1.4.1.17326.10.14.2.1.2”或“1.3.6.1.4.1.17326.10.14.2.2”策略标识符,但根必须具有上述二进制文件的SHA1指纹

    这可以防止恶意CA使用它不拥有的策略ID

    撤销检查 如果浏览器无法检查证书是否已吊销,则不会将其视为EV证书。必须进行在线撤销检查,尽管客户端可能会缓存结果

    在调用
    Build
    之前,通过在链上设置适当的标志,可以在使用
    X509Chain.Build
    时执行吊销检查

    证书透明度 这一个有点难检查,但谷歌有适当的文档上。如果证书是在2015年1月1日之后颁发的,则需要证书透明度。如图所示,一些证书也被Chrome列为白名单

    可信根 这是相当直接的,但是证书必须属于受信任的根。如果证书是自签名的,则它不能为EV。调用
    X509Chain.Build()
    时,可以再次检查此项

    多信任路径 证书可能具有多个信任路径,例如,如果证书是由交叉签名的根颁发的。如果存在多个信任路径,则所有路径都必须有效。同样,必须对所有路径执行吊销检查。如果任何路径显示证书已吊销,则证书无效

    不幸的是.NET甚至Win32都没有很好的mea