上一讲,我们讨论了单向散列函数,以及它是怎么解决数据完整性问题的。单向散列函数有两个重要的特点:
- 逆向运算困难
- 构造碰撞困难
困难要有多难?
如果凭感觉,在密码学的实践中,“完美”的单向散列函数,应该困难到没有人可以逆向运算,也没有人可以构造碰撞。
可是,只要有人发现了有那么一对数据具有相同的散列值,就意味着这个单向散列函数被破解了,不再安全了。
对于还没有被破解的算法,有没有更直观的指标让我们感受它有多安全呢?对于已经破解的算法,有没有直观的指标让我们感受它有多脆弱呢?
在密码学这么讲究量化的领域,当然不会缺少了这样的指标。其中,最常用的指标就是安全强度。
什么是安全强度?
在密码学中,安全强度通常使用**位(字节位)**来表述。比如说,安全强度是 32 位。这里的“位”是什么意思?N 位的安全强度表示破解一个算法需要 2^N(2 的 N 次方) 次的运算。
为什么要使用“位”来表示安全强度?因为这样的话,我们就可以很方便地比较不同算法的安全级别,在同一个安全级别上组合不同的安全算法。比如说,MD5 的安全强度是不大于 18 位,1024 位的 RSA 密钥的安全强度是 80 位, SHA-256 算法的安全强度是 128 位。
如果我们把上面这几个算法安排成一个组合,这个组合的强度是怎样的?这个组合的强度并不高,因为组合的强度,由最弱的算法和密钥决定。
我们先来感受一下安全强度。比如 MD5,我们说了,它的安全强度最多 18 位,也就是说,我们运算 2^18=262144 次就可以破解,按现在的计算机一毫秒一次运算的速度计算,需要 262144 毫秒,折合 4.34 分钟。
那 128 位的安全强度呢?假设我们现在有一台速度快 1000 倍的计算机,它能做到 1 纳秒运算一次。如果我们做类似上面的运算,即使我们同时使用 10 亿台计算机,破解它也需要一千万个十亿年。80 位的安全强度,同样的条件,破解大概需要 38 年。
从上面的计算,相信你可以感受到,只是稍微增加几十位的安全强度,破解难度就有巨大的提升。因为,破解难度是安全强度位数的指数(2^N)。所以,我们应该优先选择安全强度足够高的算法。
安全强度会变吗?
每一个密码算法诞生的时候,都有一个理论上的设计安全强度。注意,理论上的意思就是有可能与实际情况不符。
因为可能被破解时的安全强度根本不是设计的安全强度。
一个算法的安全强度不是一成不变的。随着安全分析的进步,几乎所有密码学算法的安全强度都会衰减。
使用多大的安全强度?
我们该使用多少位的安全强度?
业界内最新推荐的三个常用指标分别是:
- 美国的 NIST(国家标准技术研究所)
- 德国的 BSI(联邦信息安全办公室)
- 欧洲的 ECRYPT-CSA(欧洲卓越密码网络)
从上面的推荐,我们可以看到,128 位的安全强度,目前来说是安全的。不过,一个需要长期运营的系统,如果性能瓶颈不是问题,现在就可以考虑使用 256 位强度的密码算法了
选择哈希算法应该考虑哪些因素?
首先,让我们先来分析一下,还有哪些算法是可用的算法。
有哪些可用的算法?
把常见的算法分为了以下三类:
- 退役的算法;
- 遗留的算法;
- 现行的算法。
退役的算法,就是那些已经退出了历史舞台的算法,它们的安全强度很弱,一定不要用。
遗留的算法,它们存在明显的安全问题,已经不足以支撑现在的安全强度需求了,你一定不要用在新系统中了。
只有现行的算法,没有明显的安全问题,是我们可以使用的。
对于单向散列函数,目前现行的、流行的算法有:
- SHA-256
- SHA-384
- SHA-512
Note:不要单纯使用单向散列函数来处理既包含机密信息、又包含公开信息的数据,防止长度延展攻击。