假如你已经完全配好了你的 SSL:使用了强加密算法、禁用了废弃的协议,而且你提供了 100% SHA-2 的证书链。SSL Labs 给了你一个 A+ 评分,shaaaaaaaaaaaaa.com 也没发现你使用了 SHA-1。但是,有些情况下,当你访问你的网站时,Chrome 仍旧会在 URL 栏处显示一个红叉,并且说你的网站提供了 SHA-1 证书,是“肯定不安全的” 的:
URL bar showing red cross through 'https'
这可能吗?不幸的是,有可能。你的服务器所发送的证书也许并不是你的浏览器所使用的。在迁移到 SHA-2 的过程中不应该是这样的,但是由于某些 CA 糟糕的做法和用户使用了老旧的软件,有时候会出现这样的问题。具体听我一一道来。
背景知识:证书链如何工作
一个 SSL 证书必须被证书授权中心签名才是可信的。在最简单的情况下,网站的证书(终端证书)是由浏览器所信任的 CA 的(根证书)直接签名的。
简单 PKI: 终端证书由根证书直接签名
浏览器校验直接由根证书签名的证书很简单:浏览器在它的根证书库里面查找终端证书的签发者,如果找到,就使用该根证书的公钥来校验终端证书的签名。
然而,终端证书很少会由根证书进行签名。相反的,终端证书是由一个“中间证书”(有时候也称之为下级 CA)进行签名的,而中间证书则由根证书进行签名。
典型的 PKI 是使用一个中间证书
校验一个由中间证书签名的证书是困难的。浏览器不能简单地在它的根证书库中找到签发者,因为该证书并不是由根证书签名的。相反,浏览器需要找到签名该证书的中间证书,需要的话还得迭代这个过程(中间证书也许是由其它的中间证书签名的),直到沿着这个证书链找到根证书。而事实上更复杂,因为也许从终端证书到根证书有几种可能的链路。
让浏览器找到中间证书链的最简单的办法是,让服务器告诉它。这就是为什么当你部署一个 SSL 证书时,不仅仅需要你自己的证书,还需要中间证书。不过,浏览器通常会缓存中间证书,也许会使用一个缓存的证书而不是使用由你的服务器提供的证书。这就是为什么在你全部使用了 SHA-2 之后, Chrome 也许还会显示一个红叉的原因:它并没有使用你的证书链上提供的证书,而是使用了其所缓存的 SHA-1 的证书链。
理论上,这是可以避免的,如果 CA 可以正确操作、用户也运行最新的软件的话。不幸的是,现实并不总是这样,个别情况下已知导致这个问题的原因有两个。
(注意:澄清一下,生成证书链的并不是 Chrome ,而是 Chrome 交由操作系统的加密库构建证书链。加密库在 Windows 上是 CryptoAPI,Linux 上是 NSS。)
问题一:将 SHA-1 中间证书用 SHA-2 重用
当 CA 迁移到 SHA-2 时,它可以通过对已有的公钥用 SHA-2 重新签名,从而重用已有的中间证书,或者也可以生成一个带有新的公钥和主题名的新中间证书。
SHA-2 下级证书绝不应该链到 SHA-1 的 CA 下级证书上。
不幸的是,有些 CA 根本没在意这个忠告,比如某个 CA ,StartCom,仍然使用 SHA-1 中间证书签发 SHA-2 终端证书。虽然他们提供了一个 SHA-2 签名的中间证书,但是如果浏览器已经有一个缓存的 SHA-1 版本时就会有问题。
幸运的是,SSLMate 的两个 CA 都正确地从新的 SHA-2 中间证书签发证书,所以,SSLMate 的客户不需要担心这个。
问题二:过期的 NSS 和交叉签名的根证书
有时候根证书自身也由其它的根证书签名,通常这称之为交叉签名。这提供了一个抵达可信根证书的另外一条路径,交叉签名可以让一个不在你的浏览器的可信证书库中的新根证书也可以工作。当浏览器开始信任一个根证书时,交叉签名的证书就不再需要了。然而,和中间证书一样,交叉签名的证书也是可以缓存的,而在 NSS 中一个 bug 会导致 Linux 上的 Chrome 使用缓存的交叉签名的根证书,即使有更短和更新的证书链存在。如果这个缓存的交叉签名证书正好使用 SHA-1,Chrome 就会使用这个有问题的证书链并显示一个红叉,而不管你的服务器是否发送了全都使用 SHA-2 的证书链。
URL bar showing red cross through 'https'
或者,如果证书在 2016 年失效的话是这样:
URL bar for https://bugs.debian.org, with orange alert symbol
更新:由 SSLMate 的 Andrew Ayer 提供的 NSS 更新包,放到了 2015/9/5 发布的 Debian Jessie 8.2 中。
本文来自云栖社区合作伙伴“Linux中国”,原文发布日期:2015-10-12