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