消息摘要算法入门教程

1,877 阅读4分钟

前言

  消息摘要算法主要包含以下三个系列:

  • MD(Message Digest) 消息摘要算法
  • SHA(Secure Hash Algorithm) 安全散列算法
  • MAC (Message Authentication Code) 消息认证码算法

  常用于验证数据的完整性,维护映射关系,也是数字签名的核心算法之一。

特性

  消息摘要算法具有如下几个特性:

  • 运算速度快
  • 输出长度固定
  • 运算不可逆:已知运算结果的情况下,无法通过逆运算得到原文。
  • 高度离散性:输入值的细微变化,会导致运算结果差异巨大。
  • 弱碰撞性:不同输入值的散列值极低概率会出现结果相同。

  消息摘要算法主要是通过散列函数来生成摘要值,而散列函数处理的过程对原文是有损的,也是消息摘要算法具备运算不可逆特性的原因。

基础使用

  MD 算法是由著名的非对称算法 RSA 发明人之一的罗纳德·李维斯特设计,MD 系列包含 MD2、MD3、MD4 以及最典型的 MD5。

  在 Node.js 中可以利用内置的 crypto 库调用 MD5 算法:

  const crypto = require('crypto');
  const md5 = crypto.createHash('md5');

  const password = '12345678';
  const salt = crypto.randomBytes(16).toString('hex');

  const str = `${salt}:${password}` // 加盐

  const result = md5.update(str).digest('hex');

  console.log(result); // 607d0590481fe74acc0a6aab270fbe59

  SHA 算法是由美国国家安全局设计,其是在 MD4 算法的基础上演进而来,主要是想通过扩大摘要的长度来增强消息摘要的安全性。

  const crypto = require('crypto');
  const sha512 = crypto.createHash('sha512');

  const str = sha512.update('Hello World!').digest('hex');

  console.log(str); // 非常长的一段字符串

  // 861844d6704e8573fec34d967e20bcfef3d424cf48be04e6dc08f2bd58c729743371015ead891cc3cf1c9d34b49264b510751b1ff9e537937bc46b5d6ff4ecc8

  MAC 算法兼容了 MD 和 SHA 算法的特性,并在此基础上加入了共享密钥。

  const crypto = require('crypto');
  // MD5 + 共享密钥
  const hmac = crypto.createHmac('md5', crypto.randomBytes(16));

  const str = hmac.update('Hello World!').digest('hex');

  console.log(str); // f91be83fd508b8143c2c283859a5a6b0

安全性

  前面也提到了消息摘要算法的一个最大的特点就是:运算速度快。但也成为了它的一个最大弊端,随着计算机算力的发展,通过暴力枚举在可接受时间内找到其碰撞值成为了可能。

  最典型的攻击方式就是彩虹表。

彩虹表并不是简单地记录原文和摘要值的字典,其是一种权衡空间和时间成本的解决方案。

  为了抵御这种攻击的有效方式是:加盐。也就是说在加密之前,对原文混入其它的信息后,再进行摘要值的生成。

  2004年中国王小云教授公布了一种算法来快速地找到杂凑冲撞值,并且在获取到足够多的撞库原文下,能够分析出盐值。

如果存在 x !== y,H(x) == H(y),称为杂凑冲撞。

  针对上述两种攻击方式,新型的 Bcrypt 算法在加盐的基础上又加入了迭代次数的处理,使得生成摘要的过程变得缓慢,从而使得攻击者的时间成本变得不可接受,但是也使自身应用的性能受到影响。

  MAC 算法相比较加盐的方式,其密钥并不是在加密前和原文混入,而是在生成消息摘要的过程中混入,这样安全性更高

应用场景

  常见的应用场景如下:

  • 校验下载文件的完整性
  • 缓存
  • 数字签名
  • 哈希表
  • 分布式缓存

  在前端缓存优化的场景下,可以根据文件内容生成摘要信息,使其成为文件名的一部分,使得未更新的文件依然能够充分的利用浏览器的缓存。

  数字签名技术中也用到了消息摘要算法,但是相比较 MAC 算法,并不是使用共享密钥,而是采用了非对称加密算法的公私钥,这样有效地解决了 MAC 算法不具备抗否认的特性,同时安全性更高。

  哈希表和分布式缓存都是采用消息摘要算法来维护一个可靠的映射关系,当然针对这些场景,相应的算法也需要改造,比如要求散列值均匀分布等。

写在最后

  最后,如果本文对您有帮助,欢迎关注(公众号【漫谈大前端】)、点赞、转发 ε=ε=ε=┏(゜ロ゜;)┛。