关于SHA-1、SHA-2、SHA-256、SHA-384……
如果你听说过很多种形式的“SHA”,但不完全确定它的含义,或者为什么它很重要,那么请继续读下去。我们首先要解释什么是散列,然后是SSL证书如何使用散列来形成数字签名,这是了解SHA-1和SHA-2的重要背景。
什么是散列?
散列算法是一种将数据压缩为固定大小的数学函数。举个例子,如果我们通过一个叫CRC32的特定的散列算法把这个句子“快速的棕色狐狸跳过了懒惰的狗”运算以下,我们就会得到“07606bb6”——这个结果被称为“散列”。
对于计算机可能想要识别、比较或以其他方式对文件和数据串进行计算的情况来说,散列是很方便的。对于计算机来说,首先计算一个散列然后再对它们进行比较,比起对原始文件进行比较要容易得多。
散列算法的一个关键特性是确定性。世界上任何一台了解你所选择的散列算法的计算机,都可以在本地计算我们的例句的散列,并得到相同的答案。
散列算法被用于各种各样的方法——它们可以应用于存储密码、计算机视觉技术、数据库。
这里有数以百计的散列算法,它们都有特定的用途——有些是针对特定类型的数据进行优化的,有些则是为了速度、安全性等等。
今天,我们关心的是SHA算法。SHA代表安全散列算法——它的名字给出了它的目的——它是用于密码安全的算法。
加密散列算法的最重要的因素是,它们产生不可逆转且唯一的散列结果。散列结果不可逆转使得当你只有散列结果的时候,你无法用它来找出原始数据,因此使得原始数据保持了安全性和未知性。散列结果唯一使得两个不同的数据不能产生相同的散列结果——下一节将解释为什么这如此重要。
注意:为了便于阅读和理解本文,我们使用的示例数据字符串和散列算法比实际使用的要短得多。到目前为止,你所见的散列并不是任何类型的SHA散列。
数字签名
现在我们知道了什么是散列,我们就可以解释如何在SSL证书中使用它们了。
SSL/TLS协议用于在互联网上实现数据从一个设备到另一个设备的安全传输。为了简洁,看起来SSL似乎经常被解释为“加密”。但是不要忘记SSL也提供了身份验证。SSL证书文件的任务是提供身份验证所需的必要信息,特别是,SSL证书将一个特定的公钥与一个标识联系起来。
请记住,SSL/TLS协议使用非对称加密方法来保护连接。这意味着有两个密钥,每个密钥处理一半的进程:一个用于加密的公钥,另一个用于解密的私钥。每个SSL证书都包含一个公钥,客户端可以使用它来加密数据,而上述SSL证书的所有者可以安全地在其服务器上存储一个私钥,用于解密该数据并使其可读取。
身份验证对于确保SSL/TLS提供具有实际意义的安全性来说非常重要。设想一下,如果你的计算机没有可靠的方法来了解你使用的加密密钥是谁的?那么用密匙加密你的数据将不会有用,因为你不知道谁有相应的私钥来解密它。毕竟,如果你将数据直接发送给一个中间人攻击者,那么加密数据几乎没有什么用处。
数字签名是SSL证书如何提供身份验证的重要部分。当颁发证书时,你选择作为证书提供商的证书颁发机构(例如赛门铁克、Comodo、DigiCert等)对证书进行数字签名。这个签名提供了加密的证明,证明证书颁发机构签署了SSL证书,并且证书没有被修改或复制。
我们前面提到的不对称密钥再次被使用,但用于不加密的签名。在数学上,签名涉及到对数据和密钥的组合方式进行翻转(我们不会解释签名是如何创建的,因为它很快就会变得复杂起来。如果你感兴趣的话,Joshua Davies写了一篇关于数字签名如何工作的文章,你可以看一看)。为了使计算机更容易地快速、但仍然安全地创建和检查这些签名,证书颁发机构首先对证书文件进行散列运算,并标识散列结果。这比签署整个证书更加有效。
然后,数字签名提供了所需的证据,证明你所获得的证书的确是由可信的证书颁发机构颁发给该网站的。不会有花样。不会有欺骗。不会有人对证书文件进行中间人攻击操作。
数字签名是非常敏感的——任何对文件的修改都会导致签名的改变。如果我们以上一节的句子为例,并且全部小写(“快速的棕色狐狸跳过了懒惰的狗”),那么散列结果就会完全不同了。这意味着该散列的结果签名也会有所不同。即使只改变一个数千G字节的文档中的一个比特位,也会产生一个完全不同的散列结果。
这使得攻击者不可能修改合法的证书,或者创建一个看起来合法的伪造证书。不同的散列意味着签名将不再有效,并且你的计算机在对SSL证书进行身份验证时将知道这一点。如果你的计算机遇到一个无效的签名,它将触发一个错误并完全阻止一个安全连接。
SHA-1和SHA-2
现在你已结有了合适的知识背景,我们可以继续来看这个话题的核心内容了。
正如我之前所说的,SHA代表安全散列算法。SHA-1和SHA-2是该算法的两个不同版本。它们两者之间在构造上(散列结果是怎样被原始数据创建出来的)和签名的位数上都有不同和签名的位长。你应该把SHA-2看作是SHA-1的继承者,因为这是一个整体上的改进。
首先,人们关注的是位数,这被看作是重要的区别。SHA-1是一个160位的散列值。SHA-2实际上是一系列散列的“家族”,其长度各不相同,其中最受欢迎的是256位的。
SHA-2的多样性可能会导致一些混乱,因为网站和作者们用不同的方式表达它们。如果你看到“SHA-2”、“SHA-256”或者“SHA-256位”,这些名字都指向同一个东西。如果你看到“SHA-224”、“SHA-384”或者“SHA-512”,它们指的是不同位数的SHA-2版本。你可能还会看到一些站点的表述更加明确,将算法和位数都写出来,比如“SHA-2 384”。
SSL行业选择了SHA作为数字签名的散列算法。从2011年到2015年,SHA-1是主要的算法。越来越多的研究表明了SHA-1的弱点,这促使人们重新评价这一算法。从2016年开始,SHA-2成为新的标准。如果你今天收到证书,那么它必须至少使用了这种签名。
你偶尔会看到使用SHA-2 384位的证书。而你很少会看到24位的版本,它未得到批准用于公开的可信证书,你也很少会看到512位的版本,软件对它的支持范围比较狭窄。
SHA-2可能会继续使用至少5年。然而,可能会发现对该算法的一些出人意料的攻击,这可能将导致过渡更早发生。
一般SSL证书的SHA-1和SHA-2散列的长这样:
就是这么一长串码对确保SSL/TLS的安全性起到非常重要的作用。
较多位数的散列可以提供更多的安全性,因为有更多可能的组合。记住,加密散列算法的一个重要功能是生成唯一的散列结果。如果两个不同的值或文件可以产生相同的散列结果,那么就会出现所谓的“冲突”。
只有当不发生冲突的时候,数字签名的安全性才能得到保证。冲突是极其危险的,因为它允许两个文件生成相同的签名,因此,当计算机检查签名时,即使该文件实际上并未获得签名,它也可能看起来是有效的。
有多少种散列结果?
如果一个散列算法能够为每一个可能的输入产生唯一的散列值,那么会有多少个可能的散列结果呢?
一个比特位有两个可能的值:0和1。唯一散列值的可能数量可以表示为,可能的值的数量与位数的乘方。对于SHA-256算法,有2256种可能的组合。
所以,2256种组合。这是多少呢?这是一个巨大的数字。请认真对待。它使得像万亿和亿亿亿(一亿的三次方)这样的数字相形见绌。它远远超过了世界上沙粒的数量。
可能的散列值的数量越大,两个散列值产生相同散列结果的可能性就越小。
从技术上讲,有无数个可能的输入,但是输出的数量是有限的。因此,最终每一个散列算法,包括安全的算法,都会产生冲突。但我们最关心的是这样的情况发生的可能性有多大。SHA-1算法被认为是不安全的,由于它的体量和结构的原因,产生冲突的结果是可以实现的。
注意,位数很多并不意味着一个散列算法会产生安全的散列结果。该算法的结构也非常重要——这就是为什么SSL行业使用专门为加密安全设计的散列算法的原因。
向SHA-2算法的转变
去年,SSL行业经历了“向SHA-2算法的过度”。这需要对现有的数以千计的证书进行重新发布,以便新的文件可以通过SHA-2算法创建并进行签名。这还涉及到公开可信的证书颁发机构所运行的证书颁发软件(这样的软件有好几十个)的重大更新。当时出现了一些小问题,这在意料之中。
2015年12月31日是用SHA-1散列算法颁发新的SSL证书的最后期限。在很大程度上,整个行业在这个期限之前就已经停滞不前了。从那时起,我们犯了一些错误,并批准了一些特殊的案例。
但在接下来的一两年内,我们将看到绝大多数可信的SHA-1证书消亡。今天,大约有50万份SHA-1证书仍然存在。如果你遇到SHA-1证书,那么你等于看到了一个安全等级降低的标志。在谷歌Chrome浏览器中,2016年到期的所有SHA-1证书都不会显示意味着安全连接的绿色挂锁标志,而是显示与不安全的HTTP连接相同的图标。你可以点击这个图标来获得更多信息,来了解为什么会这样显示,因为还有其他与签名无关的原因。
如果你今天在你的浏览器中看到一个SHA-1证书,它应该就是下面这个样子(在谷歌Chrome浏览器中)。要看看这个页面在你的浏览器中会怎样显示,请访问站点:https://sha1-2016.badssl.com
浏览器在处理SHA-1签名的2017年失效的证书时,会产生一个更强烈的警告。这是因为签名的安全性是与它的有效期直接相关的。
保持签名的安全性
随着时间的推移,对加密系统的攻击能力将会得到提升,计算机处理能力也会变得更廉价。这使得一个有效的SHA-2签名在2020年比在2016年更不安全。由于这个原因,需要选择比当前所必须的更强大的算法,因此短期的攻击能力提升不会导致安全性方面的威胁。对于一个特定的散列算法来说,在10年内保持安全是不现实的。
世界各地的行业专家和安全研究人员都在不断分析SHA-2和其他加密散列算法,因此请放心,目前的SSL证书暂时都还有可靠和安全的数字签名。
这并不意味着密码学家只是坐等问题出现。SHA-2的继承者自然而然地被命名为SHA-3,该算法已经完成了。当需要进一步升级的时候,SSL行业可能会使用SHA-3算法作为他们的下一个选择,或者他们可能会寻找一个完全不同的算法。
要正确地研究和审查新的加密标准,然后开发支持它们的软件,需要数年的时间。有希望的是,大家都知道,这个行业至少还在一点一点向前进步。