You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
12 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 03如何设置合适的安全强度
你好,我是范学雷。
上一讲,我们讨论了单向散列函数,以及它是怎么解决数据完整性问题的。你还记得它解决问题的背后逻辑吗?就是因为单向散列函数有两个重要的特点:**逆向运算困难和构造碰撞困难**。
这两个特点使得我们仅仅修改数据中的一位,所得到的散列值和之前的相比,就会发生很大的变化。所以我们说,这两个困难也决定了一个单向散列函数的破解难度。
逆向运算越困难,破解难度越难;构造碰撞越困难,破解难度也越难。这点你应该懂了,但是,你有没有想过,困难程度要多大,才算困难?有什么指标可以衡量单向散列函数的破解难度?
一下出现这么多问题,是不是有点意外?其实,**密码学就是在和千奇百怪的问题****的****纠缠中获得进展的**。这一次,我们来讨论困难有多难以及和破解难度相关的问题。
## 困难要有多难?
我们要探讨的第一个问题就是,一个单向散列函数的逆向运算和构造碰撞要困难到什么程度,它才能算是一个合格的单向散列函数呢?**如果凭感觉,在密码学的实践****中********我们心中“完美”的****单向散列函数,应该困难到没有人可以逆向运算,也没有人可以构造碰撞。**
可是,只要有人发现了有那么一对数据具有相同的散列值,不管这个人什么出身、什么来历,也不管这对数据有多么的千奇百怪,更不管破解方式是多么的不合常理,这个结果就意味着这个单向散列函数被破解了,不再安全了。
比如说下面的两段数据具有相同的MD5算法散列值MD5是一个单向散列函数
细心看的话你会注意到例子中的afbfa202和afbfa200以及6da0d1d5和6da0d155这两段数据是有差异的但是结果显示它们的散列值却是相同的。在这个例子里我们并不需要深入了解破解MD5的具体算法和实现我们只需要知道MD5被破解了MD5就不能够继续使用了。
```
M1:
4dc968ff 0ee35c20 9572d477 7b721587 d36fa7b2 1bdc56b7 4a3dc078 3e7b9518 afbfa202 a8284bf3 6e8e4b55 b35f4275 93d84967 6da0d1d5 5d8360fb 5f07fea2
M2:
4dc968ff 0ee35c20 9572d477 7b721587 d36fa7b2 1bdc56b7 4a3dc078 3e7b9518 afbfa200 a8284bf3 6e8e4b55 b35f4275 93d84967 6da0d155 5d8360fb 5f07fea2
Hash: MD5(M1) = MD5(M2)
008ee33a 9d58b51c feb425b0 959121c
```
我所了解的**现代单向散列函数****在****算法意义上的破解,都是通过宣布找到一对散列值碰撞的数据的形式发布的**。还记得什么是散列值碰撞吧?就是指两份散列值的数据是相同的。
只有当你找到了这样的一对碰撞,你才能验证破解算法的有效性,算法的破解才能让人信服。
不过,话说回来,这固然是一个好的办法,可是对于还没有被破解的算法,有没有更直观的指标让我们感受它有多安全呢?对于已经破解的算法,有没有直观的指标让我们感受它有多脆弱呢?
在密码学这么讲究量化的领域当然不会缺少了这样的指标。其中最常用的指标就是安全强度Security Strength
## 什么是安全强度?
在密码学中安全强度通常使用“位”字节位来表述。比如说安全强度是32位。这里的“位”是什么意思**N位的安全强度表示破解一个算法需要2^N(2的N次方)次的运算**。
为什么要使用“位”来表示安全强度因为这样的话我们就可以很方便地比较不同算法的安全级别在同一个安全级别上组合不同的安全算法。比如说MD5的安全强度是不大于18位1024位的RSA密钥的安全强度是80位 SHA-256算法的安全强度是128位。
在这里给你出个小问题,如果我们把上面这几个算法安排成一个组合,这个组合的强度是怎样的?这个组合的强度并不高,因为**组合的强度,由最弱的算法和密钥决定**。所以,把它们安排成一个组合,不是一个好的想法。你可以先记下来,我们后面会再讨论算法组合的基本原则。
回到安全强度这个话题谈论单向散列函数算法之前让我们先来感受一下安全强度。比如MD5我们说了它的安全强度最多18位也就是说我们运算2^18=262144次就可以破解按现在的计算机一毫秒一次运算的速度计算需要262144毫秒折合4.34分钟。
MD5现在就是这么弱。其实在2006年就有研究者宣布研究成功即使是那时候的笔记本电脑在一分钟之内也可以找到一对散列值碰撞的数据了。
那128位的安全强度呢假设我们现在有一台速度快1000倍的计算机它能做到1纳秒运算一次。如果我们做类似上面的运算即使我们同时使用10亿台计算机破解它也需要一千万个十亿年。80位的安全强度同样的条件破解大概需要38年。
从上面的计算相信你可以感受到只是稍微增加几十位的安全强度破解难度就有巨大的提升。因为破解难度是安全强度位数的指数2^N。所以**在****实践****中,我们应该优先选择安全强度足够高的算法。**
## 安全强度会变吗?
每一个密码算法诞生的时候,都有一个**理论上的设计安全强度**。注意理论上的意思就是有可能与实际情况不符。比如单向散列函数SHA-1在1993年发布的时候它的设计安全强度是80位。
12年后在2005年2月中国密码学家王小云教授带领的研究团队发现SHA-1的安全强度小于69位远远小于设计的80位。从此SHA-1的安全强度开始一路衰减。很快2005年8月王小云教授的团队又改进了破解算法发现SHA-1的安全强度只有63位了。
2015年10月密码学家马克·史蒂文斯Marc Stevens皮埃尔·卡普曼Pierre Karpman和托马斯·佩林Thomas Peyrin的研究团队发现SHA-1的安全强度只有57.5位。
更要紧的是他们估算如果使用云计算按照2015年亚马逊EC2云计算的定价和算力**57位的安全强度2015年的破解成本大致是10万美元**,你可以感受下密码强度和破解成本的数字。
2020年1月密码学家盖坦·勒伦GaëtanLeurent和托马斯·佩林Thomas Peyrin又发现 SHA-1的攻击复杂度是63.4位攻击成本大约为4.5万美元。
根据上面的数字,我们可以感受到,**一个64位安全强度的密码算法它现在的破解成本大概是5万美元左右**。不同类型的算法破解成本也许有很大偏差但是我们依然可以大致估算攻击成本。5万美元无论是对于一个有组织的研究机构还是犯罪集团都是一个很小的数目。
这可以说明什么如果一个系统的安全强度低于64位它的安全性几乎形同虚设。
通过SHA-1的例子我想强调的就是**一个算法的安全强度不是一成不变的。随着安全分析的进****步****,几乎所有密码学算法的安全强度都会衰减**。今天看起来安全的算法,明天也许就有破解的办法。所以,**一个好的安全协议,应该考虑备份计划和应急计划**(参见极客时间[《代码精进之路》](https://time.geekbang.org/column/intro/100019601)专栏第41讲“预案代码的主动风险管理”里提到的双引擎和降落伞设计
## 使用多大的安全强度?
现在,我们已经知道了什么是安全强度,也感受了一下不同密码算法的安全强度,知道了安全强度是会变的。那么,我们今天要讨论的最后一个话题是,我们该使用多少位的安全强度?
多少位的安全强度算是安全的呢?其实,我们要是想找到一个确切的答案,我们不仅要看具体的使用场景,还要综合考虑性能和安全强度。是不是觉得会有点复杂和困难?
不过,**我****可以给你一个****建议,就是****参考、遵****循常用的推荐指标**。
业界内最新推荐的三个常用指标分别是:
* **美国的NIST国家标准技术研究所)**
* **德国的BSI联邦信息安全办公室**
* **欧洲的ECRYPT-CSA欧洲卓越密码网络**。
为了让你更直观地了解这三个指标,我还给你做了一个小结。
![](https://static001.geekbang.org/resource/image/22/9e/22828b7a07376a9afd082fdddfa1089e.jpg)
看到这个表,是不是感觉还是摸不到头脑?该怎么使用这个表呢?我们一起来看一个例子。
假设我们现在要设计一个新系统预期寿命十年也就是我们要从2020年开始运营运营到2030年结束。而且我们还要保证到2030年这个系统还是足够安全的。
首先我们按照NIST的建议2030年后112位的安全强度已经不能使用了所以如果我们遵守NIST的推荐指标这个系统就不建议选择112位安全强度的算法。
在BSI建议里2030年之前够用的话我们应该选择256位的安全强度。
我们再看ECRYPT-CSA的建议128位的安全强度只能用于2028年之前。到了2030年128位的安全强度就不能满足ECRYPT-CSA的建议了。所以如果我们遵循ECRYPT-CSA的建议这个系统就需要使用256位的安全强度。
你发现了吗ECRYPT-CSA的建议为什么这么保守其实这种保守的姿态背后隐含了对量子计算时代来临的担忧。在量子计算时代128位的安全强度稍显脆弱可是256位的安全强度还是足够的。**虽然量子时代还没有到来,但是我们现在就要开始考虑量子时代的挑战了。**
从上面的推荐,我们可以看到,**128位的安全强度目前来说是安全的**。不过,一个需要长期运营的系统,**如果性能瓶颈不是问题,现在就可以****开始****考虑使用256位强度的密码算法了**。
还记得我们上面提到的安全强度不足18位的MD5函数吗这么弱的安全强度几乎已经没有实用价值了。那么有哪些单向散列函数能达到128位甚至256位的安全强度这些问题我们下一次来讨论。
## Take Away今日收获
今天,通过讨论单向散列函数的“两个困难程度”,我们知道了困难有多难,还分析了破解强度的计量办法、安全强度的衰减、常见的安全强度推荐指标,以及一些可以直观感受的数字。
这些直观感受的数字可以帮助你建立对密码算法安全强度的印象。比如一个64位安全强度的密码算法它现在的破解成本大概是5万美元左右。再比如128位的安全强度按照现有的计算能力破解它需要一千万个十亿年。
这一讲,通过对安全强度的讨论,我们要:
* **知道****密码学****安全强度通常使用位来表示;**
* **知道128位的安全强度****暂时****还是安全的;**
* **知道长期的系统可以考虑开始使用256位安全强度的算法了。**
## 思考题
如果你能够使用你知道的所有的计算机包括你的个人计算机和公司的计算机系统比如亚马逊的云系统你能不能大概估算一下破解64位的安全强度、80位的安全强度、128位的安全强度分别都需要多长时间
这是一个能够帮助你建立对安全强度直观概念认知的办法。
欢迎在留言区留言,记录、讨论你的估算数据。
好的,今天就这样,我们下次再聊。