关注网络安全
和行业未来

Cert Spotter是怎样解析2.55亿份证书的

本文发布在SSLmate博客,详细介绍了其产品Cert Spotter解析SSL证书的过程。

当Cert Spotter扫描证书透明日志为你的域查找SSL证书时,它的一项工作就是:不要错过证书。在一个理想的世界中,这是很容易的。Cert Spotter是用Go语言编写的,而Go语言的标准库有一个令人愉快而且易于使用的证书解析器,它可以提取一份证书的所有相关信息:域名、公钥、截止日期等等。

不幸的是,现实世界并不是那么容易的。尽管有一些标准规定了如何对证书进行编码,但这些标准是复杂且难以遵循的,而且,即使这些标准非常清晰,证书颁发机构也仍然会想方设法违反它们。结果就是,证书透明日志中充斥着不符合标准的证书。由于Go语言的证书解析器严格遵循标准,因此,它无法解析很多这样不符合标准的证书。如果Cert Spotter使用Go语言的证书解析器,它就会错过一些证书。理想状况下,这些证书是无害的,因为TLS客户端也会拒绝它们,但是实际上,许多TLS客户端的证书解析器都是非常宽松的。因此,Cert Spotter至少需要与可以想象的最宽松的TLS客户端一样宽松。

在排除了Go语言的标准解析器之后,我们曾经尝试过使用谷歌的证书透明库中的一个Go语言解析器的分支,它将几个最常见的编码错误作为警告处理。不幸的是,这还不够,还有一些证书仍然无法解析。我们考虑过对额外的错误进行特殊侦测,直到每一个记录的证书都可以解析,但是这种机制看起来很脆弱,并且在遭遇敌对模型的情况下很容易出现故障:一个攻击了证书颁发机构的黑客可能会颁发一个带有编码错误的证书,而Cert Spotter还没有对这种情况进行特殊处理。

相反,我们使用Go语言的卓越的ASN.1库(ASN.1是用来表示证书的语法结构。)编写了一个定制的、极为宽松的证书解析器。下面是我们使用的一些技术,这些技术可以确保Cert Spotter能够解析所有记录到证书透明日志的证书——这些证书有2.55亿份。

延迟解析

证书包含许多信息数据,但并不是所有的信息都同等重要。对于监视器来说,最重要的信息就是域名,因为域名告诉我们谁需要了解这个证书。即使Cert Spotter不能理解证书的其余部分,我们至少也要提醒域名所有者,这样他们就可以采取适当的措施。因此,Cert Spotter使用了延迟解析,并且只在必要时单独解析证书的不同部分,这样,在证书的某个部分中出现的问题就不会对解析证书的其余部分造成影响。

Go语言的ASN.1库使得延迟解析变得容易,这是由于asn1.RawValue的数据类型的原因,该数据类型允许一个数据结构的一部分保持未解析状态。Cert Spotter使用asn1.RawValue类型来解析整体的证书数据结构,然后对单个RawValue进行单独的解析。下面是Go语言解析器使用的TBSCertificate数据结构的定义,后面是Cert Spotter使用的类似的数据结构。两个数据结构的字段都是相同的,但是Go语言解析器使用的是实际类型,整个数据结构都必须成功被解析,然后才能解析证书,而Cert Spotter使用的是asn1.rawvalue类型:

Go语言解析器的数据结构:

type tbsCertificate struct { 
        Raw                asn1.RawContent 
        Version            int `asn1:"optional,explicit,default:0,tag:0"` 
        SerialNumber       *big.Int 
        SignatureAlgorithm pkix.AlgorithmIdentifier 
        Issuer             asn1.RawValue 
        Validity           validity 
        Subject            asn1.RawValue 
        PublicKey          publicKeyInfo 
        UniqueId           asn1.BitString   `asn1:"optional,tag:1"` 
        SubjectUniqueId    asn1.BitString   `asn1:"optional,tag:2"` 
        Extensions         []pkix.Extension `asn1:"optional,explicit,tag:3"` 
}

Cert Spotter的数据结构:

type TBSCertificate struct { 
        Raw                asn1.RawContent 
        Version            int `asn1:"optional,explicit,default:1,tag:0"` 
        SerialNumber       asn1.RawValue 
        SignatureAlgorithm asn1.RawValue 
        Issuer             asn1.RawValue 
        Validity           asn1.RawValue 
        Subject            asn1.RawValue 
        PublicKey          asn1.RawValue 
        UniqueId           asn1.BitString `asn1:"optional,tag:1"` 
        SubjectUniqueId    asn1.BitString `asn1:"optional,tag:2"` 
        Extensions         []Extension    `asn1:"optional,explicit,tag:3"` 
}

 

一旦解析了整个数据结构,Cert Spotter就可以通过访问它们的FullBytes成员来解析单独的RawValue,方法如下:

serialNumber := big.NewInt(0) 
asn1.Unmarshal(tbs.SerialNumber.FullBytes, &serialNumber)

Cert Spotter在解析证书的主题时也使用了延迟解析。主题是一系列的属性,如机构名称、国家代码和公用名称。Cert Spotter只关心公用名称,因为它可能包含一个域名(这是不赞成使用的,但是一些TLS客户端仍然支持它,所以Cert Spotter需要了解它)。Cert Spotter使用asn1.RawValue类型作为属性值,如果属性类型是公用名称,则只需要解析RawValue

宽松的字符串解码

ASN.1库定义了大量的字符串类型,其中任何一种都可能用于对证书的公用名称进行编码。其中两个字符串类型是特殊的,它们是PrintableStringIA5String,它们带来了一些问题。PrintableString类型是ASCII码的一个子集,它禁用了一些字符,例如星号。而证书颁发机构通常会包括这些字符,特别是对于通配符证书的颁发机构来说更是这样。IA5String类型就是ASCII码,但证书颁发机构通常包含Latin-1字符。因此,Cert Spotter把PrintableStringIA5String两个类型都看作是Latin-1字符,并且不关心字符串是否包含了禁用字符。

DNS名称中的IP地址

尽管在DNS名称和IP地址中有单独的主题备用名称(SAN)类型,但Windows系统过去缺乏对IP地址主题备用名称的支持,相反,它会将一个DNS主题备用名称中的以字符串编码的IP地址解析为IP地址。因此,Cert Spotter会检查DNS主题备用名称是否可以被解析为IP地址,如果可以的话,它会将其视为一个IP地址。

DNS名称中的NUL字节

2009年,Moxie Marlinspike为DNS名称www.paypal.com<NUL>.secureconnection.cc获得了一个证书。因为Marlinspike拥有域名secureconnection.cc,所以他可以授权颁发该域名的证书。然而,由于在DNS名称中间有NUL字节,一些TLS客户端认为该证书是针对www.paypal.com的,这使得Marlinspike可以对这些客户端模仿PayPal。

当Cert Spotter看到一个包含一个NUL字节的DNS名称时,它不仅将这个证书视为对完整的DNS名称有效,而且会将其视为对NUL字节之前的部分有效。对于www.paypal.com<NUL>.secureconnection.cc来说,Cert Spotter将会对paypal.comsecureconnec.cc的所有者都发出警告。

DNS名称中的URL

令人难以置信的是,证书颁发机构已经将整个URL放入了证书的DNS名称中。尽管这些DNS名称在TLS客户端中不起作用,但是URL中的域名的所有者仍然应该了解该证书,因为这可能是对域的更大规模攻击的证据。因此,Cert Spotter解析URL,从它们中提取域名,并通知域的所有者。

重复的扩展

证书颁发机构有时会颁发一些包含同一类型的多个扩展的证书。如果一个证书包含多个主题备用名称扩展,那么Cert Spotter将从所有这些扩展中提取出域名。而一个稚嫩的解析器可能只使用第一个或最后一个主题备用名称扩展,这将会丢失关键信息。

不间断的监控

虽然Cert Spotter能够解析所有2.55亿份被记录的证书,并曾经尝试过预测所有类型的编码错误,但是一个Cert Spotter无法解析的新的证书仍然可能出现。SSLMate对不可解析的证书进行不间断的监控,如果发现一个(目前还没有发生过),我们将修复Cert Spotter,这样它就可以解析这个证书,然后重新处理这个证书,从而让域的所有者得到通知。

结语

在选择证书透明监视器来跟踪你的域的SSL证书时,重要的是选择一个不会错过证书的监视器,即使这种监视器的编码非常糟糕。使用标准证书解析器的监视器将会丢失那些畸形的证书,即使这些证书对你的基础结构造成了风险。Cert Spotter的定制的、超级宽松的证书解析器是被非常仔细地编写出来的,它可以获取每一份证书,这样你就可以在需要的时候得到通知。

 

稿源:sslmate

评论 抢沙发