# 数据加密用 MD5、SHA-1 合适么?

日常开发工作中,我们经常会遇到数据需要加密的场景。比如用户的登录密码需要在数据库中以密文方式存储;校验明文传输的数据是否被篡改过。

这种时候,可能你的第一反应就是“我们可以用 md5、sha1 函数来完成数据加密”。那么你是否想过,这两个函数到底是什么?适合在什么时候用?让我们一起来探索一下。

# 什么是单向散列函数?

MD5、SHA-1 这两个加密函数在密码学上,都归属于「单向散列函数」,跟它们同属一类的还有:MD2、SHA-0、SHA-256、SHA-512 等单向散列函数。

那么什么是单向散列函数呢?从字面上解读的话,这类函数的理解主要落在「单向」和「散列」两个词上。在密码学上,单向函数、散列函数分别是不同类型的函数。他们分别是:

  1. 单向函数是正向计算容易、逆向运算困难的函数
  2. 散列函数是一个可以把任意大小的数据,转换成固定长度的数据的函数

所以单向散列函数其实就是这两者的结合,它的主要特征体现就是:逆向运算困难、构造碰撞困难。

# 保护数据完整性

基于单向散列函数逆向运算困难、构造碰撞困难的特性,它主要的作用场景就是为了解决数据信息完整性的问题。反应到我们日常实际遇到的业务场景比如有开头提到的「密码加密」以及「数据签名」。

在密码加密的场景下,使用单向散列函数是为了保证用户注册初始化/刚修改的新密码,与每次登陆时所使用密码明文一致(明文数据完整未被篡改)时可认证通过进入系统。

在数据签名的场景下,使用单向散列函数是为了保证在数据传输过程中,签名所保护的数据信息没有被恶意篡改(比如付款金额从 99 改成 0.1)。当然正常情况下,数据签名时双方还会同时持有一个约定好的密钥数据。

另外在一些文件指纹、信息集指纹的场景下,单向散列函数均有着广泛的使用。

# 它们安全么?

了解了单向散列函数的适用场景后,我们再看看它们在安全上的问题。

正式讲算法安全问题之前。我简单的搜索了一下目前我们基于 iMingYuan 框架下的业务代码中,用到了 md5 加密函数的代码。我发现从少量仓库的代码来看,至少从 2018 年至今,我们系统中各处的业务功能陆续有在使用 md5 进行数据加密。甚至连 OSS、aliyun、wxPay 相关的一些 SDK 中均搜出了对 md5 函数的使用。那么我们接着看下去,看看 md5 函数到底安不安全。

衡量一个加密函数的安全强度,有一个重要的指标,那就是:破解该算法所需进行的运算次数。衡量的单位是「位」,如果一个加密函数,只需要计算 1024(2^10) 次就可以破解,那么我们将他的安全强度称之为 10 位。

在密码学领域中最新推荐的三个常用指标分别是: ● 美国的 NIST(国家标准技术研究所) ● 德国的 BSI(联邦信息安全办公室) ● 欧洲的 ECRYPT-CSA(欧洲卓越密码网络)

图片

目前 MD5 的安全强度仅有 ≤18 位,而 SHA-1 的安全强度也只有 57.5 位。下图是目前业内常用的一些单向散列函数的摘要信息对比:

图片 图片 图片

可能看表格只是一个安全强度的数字,大家心里没有准确的一个关于「到底有多强」的安全强度概念。我举个栗子:MD5 的安全强度 18 位来看,如果假设现在计算机 1 毫秒可以运行一次计算,那么破解一个 MD5 密文,我们仅需花费 2^18 = 262144ms,折合仅需 4.34 分钟即可。 或许你会很惊讶,但目前 MD5 的安全强度就是这么弱。

那么 57.5 位安全强度的 SHA-1 函数呢?在 2015 年的时候,按照当时亚马逊云计算算力的定价来估算,57 位安全强度的破解成本大致是 10w 美元。而到了 2020 年一些密码学家最新的研究表明,当下 SHA-1 的攻击成本仅为 4.5w 美元。这个数字对于一些高价值的数据资源来说,都是非常小的数目。

# 用什么才安全?

在加密算法的选择上,有个简单的标准:一般而言,应该选用现行的、流行的算法。现行推荐的算法,保证了算法的安全性。流行的算法,成熟的实现会考虑实现优化,包括 CPU 扩展指令的支持。

根据前文提到过的目前相对严格的 ECRYPT-CSA 建议来看。如果我们正在做的系统/功能你预估它会运行 5-10 年,那么我们可以使用 128 位安全强度的算法,比如 SHA-256、SHA3-256。如果预估系统至少运行 10 年、20 年以上的,最好还是使用 256 位强度的算法,比如 SHA-512、SHA3-512 等。

ps: 128 位安全强度的算法,建议只用在 2028 年之前主要是考虑到可能即将到来的量子计算时代。128 位安全强度的算法在我们当下的云计算时代中,还可以保有较高的抗破解安全性,但又不足以对抗量子计算的算力攻击。而 512 位安全强度的算法,至少从目前来看是足以抵御量子计算的算力攻击。

# THE END

最后,希望大家今后在进行相关开发工作时,能够选择合理的算法来支撑功能的实现,而不再是盲目的使用 md5、sha1 这些函数。或是遇到与多方系统开发沟通协作时,能够在数据安全的问题上持有初步的判断并能合理的分析问题。thx