乐趣区

关于密码学:密码学概念科普加密算法数字签名散列函数HMAC

明码散列函数

明码散列函数 (Cryptographic hash function),是一个单向函数,输出音讯,输入摘要。次要特点是:

  • 只能依据音讯计算摘要,很难依据摘要反推音讯
  • 扭转音讯,摘要肯定会跟着扭转
  • 对于不同的音讯,计算出的摘要简直不可能雷同

依据散列函数的上述特点,能够利用在保留明码、数据防篡改和完整性爱护、数字签名等方面,前面介绍其余概念的时候也会提到。

在网上下载文件时,常常会提供 MD5 值供校验。因为文件理论可能是从世界各地的镜像站下载的,有可能会被篡改,所以下载实现之后计算一下 MD5 看是否统一,就晓得是否被篡改了。

个别零碎在设计时,都不会间接保留明码原文,避免明码透露。这时能够应用散列函数保留原始明码的摘要。依据散列函数的特点,即使摘要透露了,也很难反推出明码是什么。只有正确的输出了原始明码,能力计算出完全相同的摘要。

尽管散列函数是单向的,但能够应用彩虹表用空间换工夫。就是把常见的组合的摘要都计算出来,这样拿到一个摘要之后,去比对一下就有可能找到原始信息。例如能够去搜索引擎上搜寻一下 456b7016a916a4b178dd72b947c152b7 这个字符串,很容易就能晓得他的原文是什么。

为了防止被彩虹表攻打,能够在计算摘要时,增加一点随机的货色进去再计算摘要,这个货色叫盐值 (salt)。因为盐值足够长且是随机的,这样想通过当时计算的彩虹表去碰撞就会更艰难了。例如下面那个字符串很容易能搜到是 admin 的 MD5 值。而如果咱们给 admin 前面拼接上 P6R8ERaZ,再计算出 adminP6R8ERaZ 的 MD5 值 70a1a6831709d7e7cb6cc35ccdfdbd39,再去搜寻这个值就很难找到他的原文了。下面只是个例子,理论利用中,盐值不是简略的增加到原始音讯的前面。

常见的散列函数包含 MD5、SHA-1、SHA-2 等。SHA-2 蕴含 SHA-256/224、SHA-512/384 等。其中 MD5、SHA-1 曾经被证实不平安,举荐应用 SHA-2 系列的。

本文的例子中都应用 MD5,是因为 MD5 生成的摘要是 128 位的,更短一点好写。

MAC/HMAC

下面提到下载文件时可能会提供文件的 MD5,供校验文件是否被篡改。这样做有个前提是这个 MD5 自身不会被篡改。例如下载的文件放在镜像站,而 MD5 自身是放在 HTTPS 的源网站的。

但很多时候摘要自身也是不能平安传递的,这时如果还应用摘要去校验就失去了意义,因为篡改音讯的人间接把摘要一起篡改了就行了。

这种状况能够应用音讯认证码 (Message authentication code, MAC)。MAC 是依据一个密钥,应用一个算法,把音讯计算成一个摘要。通信的另一方,应用雷同的密钥和算法,计算出摘要,比照是否统一,能够验证音讯是否被篡改。

将音讯和 MAC 一起传递,如果音讯被篡改了,但中间人没有密钥,无奈计算出新的 MAC,音讯接管方就能校验出音讯被篡改了。

理论应用中通常应用的是 HMAC (keyed-hash message authentication code),也就是应用明码散列函数,联合一个密钥,去计算音讯的摘要。

举个例子,咱们能够定义这样一个 MAC 算法:原始音讯前面间接拼接密钥,而后应用 MD5 算法计算摘要。假如通信单方约定的密钥是 secret。当我要发送 Hello World 时,就计算出 Hello Worldsecret 的 MD5 值 (88266e1db8f6446d33071e6b1b14747f) 作为 MAC 一起发送。如果有人截获了这个音讯删了一个字母变成了 Hello Worl,他不晓得咱们约定的密钥 secret,就没方法计算出新的 MAC。接管方收到 Hello Worl 拼接上 secret 计算出的 MAC 是 d5f4677a2612e26c50b55ba257743170,就会发现音讯被篡改了。

OTP

因为大多数用户设置的明码强度可能不够高,又或者可能在不平安的环境登陆过导致明码曾经透露了。所以很多网站除了明码之外还须要其余验证形式,进步安全性。

这个时候就须要应用一些只有你和网站之间晓得的信息来验证,而且这个信息最好是一次性的,防止被人截获之后能够屡次用于验证。这个就是 OTP (one-time password)。

例如很多网站都会发送短信验证码或邮箱验证码,这个就属于一种 OTP。只有网站晓得你的手机号和随机生成的验证码是什么,也只有你领有这个手机号能力收到这个验证码,这个验证码用一次就会生效。

HOTP

应用短信验证码、邮箱验证码作为 OTP,还得依赖邮件服务商或者通信运营商等,而且没方法离线。

依据后面提到的 HMAC 的概念,咱们能够在注册账号的时候和网站约定好一个密钥,这个密钥只须要在第一次生成的时候传递一次,单方都保留好。当前须要应用 OTP 验证的时候,咱们就都用这个密钥去计算某个音讯的 HMAC 值,用这个值作为 OTP 去做认证。这就是 HOTP (HMAC-based one-time password)。

应用 HOTP 同样能够达到验证的目标,还能够离线,不必依赖短信和邮箱服务器了。

TOTP

应用 HOTP 时,单方独特用于计算摘要的信息能够是一个计数器,例如初始时单方都是加密 1,每用一次就递增。然而这个计数器可能呈现单方不统一的状况,所以可能还须要调整一下。

咱们能够更进一步约定单方都去计算一个公开的信息的摘要,这个信息单方永远都会是统一的,会更不便一些。这个信息还要随工夫变动,否则每次计算出来的摘要是同一个,就不是 OTP 了。既然这样,那间接把工夫作为信息去计算摘要就好了,这就是 TOTP (Time-based one-time password) 了。

当然咱们还要略微做些变通,如果间接把准确到秒的工夫作为信息去计算摘要,还没等输出呢,就曾经过期了。所以个别都会有一个余量,比方除以 30 秒并向下取整,这样每 30 秒内计算出来的后果都是雷同的。

HOTP 和 TOTP 都是有公开的规范的,规定了密钥是怎么编码的、应用哪种 HASH 函数、有效期是多长时间、生成的数字是几位的等等。依照这个规范,实践上本人手敲计算器都能计算出雷同的 TOTP 值。要备份也很容易,只有把后面说的那个和网站约定的独特的密钥备份下来就行了。

国外支流网站都反对应用 TOTP 作为二次验证的伎俩,Google 和微软也都有本人的身份认证器利用。因为 TOTP 是一个规范,所以不是肯定要用这些利用,更不是每个网站都要装置一个 APP。能够找一个反对 TOTP 的 APP 对立治理所有网站的就能够了。例如 Keepass,反对所有平台,还能够治理明码。

有些银行的平安介质除了 U 盾外,还有一种长得像一个小计算器一样的电子明码器,其实这个货色也算是一个 TOTP 和 HOTP 的利用。这个货色关上之后就会有一个每 30 秒更换一次的 6 位数字,办理业务时须要把这个数字输出进去,这就是 TOTP。有些场景还须要把网银或手机银行上弹出的几位数字输出到电子明码器中,而后再把明码器上生成的数字输出回网银或手机银行,这就是 HOTP。这外面的软件算法应该和下面说的差不多,做成一个硬件能够避免密钥透露、失落。

对称加密算法

如果想加密一段信息,最容易想到的形式就是先随机生成一段足够长的密钥,例如 01010101011010101,而后用这个密钥对明文的每一位做异或操作,就失去了密文。如果这个密钥足够随机,实践上没有人能依据密文间接还原明文。解密时应用密钥再对密文做一次异或操作,就失去了明文。这基本上就是流加密的原理了。

这种须要加密和解密单方具备雷同信息(密钥)的加密算法,叫做对称加密算法。

流加密就像下面例子一样,间接对每一位加密,效率高。但须要密钥和加密的数据一样长,很难做到,理论利用并不多。

另一种更罕用的对称加密算法是分组加密算法,又叫块加密,就是把明文依据算法和密钥长度分成一块一块的去加密。

因为明文不太可能总是密钥长度的整数倍,所以不够的局部就须要填充,比方全填 0,或者依照其余什么规定填充,这个叫做填充模式。

分组加密解决每组数据有几种不同的工作模式。最直观的就是把每一块独立加密再拼接起来就行了,这就是 ECB 模式(Electronic codebook,电子密码本)。但这样的特色很容易被人辨认。更平安一点的例如 CBC 模式(Cipher-block chaining,明码分组链接),每一块都是在上一块加密的根底上进行加密的。

另外为了保障雷同的明文屡次加密的后果不一样,还要应用一个随机生成的初始化向量 (IV),作用就跟盐值的作用差不多。

应用 OpenSSL 时,能够通过参数设置加密算法和工作模式,如果不指定默认是 CBC 模式。GPG 默认应用的是定制过的 CFB 模式,不能自己抉择。

常见的对称加密算法有 DES、3DES、AES。其中 DES 曾经不平安了,3DES 也不齐全平安。倡议应用 AES,AES 算法的密钥长度有 128、192、256 三种。

KDF/PBKDF2

咱们在理论应用对称加密算法时,本人想的明码的强度通常是不够的。

例如 AES 算法最短的密钥长度也有 128 位,也就是 16 个字节,粗略的预计大略是 16 个字符的明码长度。理论不能这样比拟,因为 128 位的密钥意味着有 2^128 ≈ 3 * 10^38 种组合的可能。而 16 个字符的明码,如果只蕴含字母和数字,大略只有 (26 + 26 + 10)^16 ≈ 5 * 10^28 种组合,就算算上全副 ASCII 可打印字符,也只有 95^16 ≈ 4 * 10^31 种组合。而且理论应用中,个别人不可能真的想到和记住这么简单的明码。

所以如果间接应用本人想到的明码作为密钥去加密数据,理论暴力破解起来的难度至多会降落几个数量级,基本达不到 128 位的密钥强度。

为了解决这个问题,咱们能够基于输出的明码去派生出一个更加平安的密钥。这个派生的过程要足够的慢、足够的随机。足够随机是为了避免被彩虹表攻打、足够的慢是减少暴力破解的难度。

例如原本 1 毫秒就能试一个明码,如果是 6 位数字的明码,只须要不到两分钟就能破解进去了。而如果这个密钥派生的过程须要 1 秒,那么同样是 6 位数字的明码,也须要大略 69 天能力试出来。

用于派生密钥的函数叫做 KDF (Key derivation function),目前罕用的是 PBKDF2 (Password-Based Key Derivation Function 2)。通过退出随机的盐值,应用 HMAC 算法,迭代很多轮次,失去最终的密钥。

GPG 的 s2k (string to key) 系列参数,就是用来管制 KDF 算法的相干参数。SSH 用的是 bcrypt pbkdf。OpenSSL 能够在命令中指定 pbkdf 算法和迭代次数。

非对称加密算法

依据 GPG 使用指南中的形容,间接应用对称加密算法加密,很多时候如何替换密钥就成了一个问题。而非对称加密则利用一些数学问题,使单方能够不须要具备雷同的密钥也能加解密音讯。

非对称加密算法个别利用的是离散对数、大数合成、椭圆曲线等数学问题。不论是哪个都超出了我的常识领域,但这不影响咱们了解非对称加密。

咱们能够假如这是一个只会计算乘法、没人会算除法的世界。那么如果有这样一对数字 2 和 0.5,就能够把他们别离作为公钥和私钥。例如我能够把 2 作为公钥广而告之,谁想给我发送数字(例如 5),就把它乘 2(失去 10)发过来,我收到之后再乘 0.5 就失去了原始数字(5)。而如果其他人拿到这个 10,即使晓得公钥是 2,然而因为不会计算除法,所以也无奈计算出原始数字。

正是因为非对称算法利用了各种数学计算,所以没有对称加密算法那种简略粗犷的位运算高效,性能大略比对称加密算法慢 10 倍以上。

所以个别不会间接应用非对称加密算法去加密原始信息,而是去加密一个短一点的对称加密密钥,而后再用这个对称加密密钥去加密真正的音讯。当然实践上说,联合分组加密算法的工作模式,应用非对称加密算法间接去加密长一点的原始信息也是齐全可行的,只是慢了点。

非对称加密算法的用处很宽泛,除了根本的加密之外,还能够用于数字签名、密钥协商等场景。

数字签名

如果间接应用私钥加密,同样也只有公钥能解密。但因为公钥曾经广而告之了,这种加密就没有窃密的意义了。但能够证实这个音讯的确是由这个持有这个公钥对应的私钥的人收回的,而且没有被改变过。就像是签名一样,所以叫做数字签名。

同样的基于性能的思考,个别不会、也没必要用私钥间接加密(签名)整个音讯。依据后面明码散列函数的特点,咱们只须要先对音讯计算个摘要,再对摘要进行签名,就能够达到给整个音讯签名雷同的成果了。

这就有点像要给一打文件盖章,没必要一页一页的去盖章,能够在这一打文件的侧面盖一个章。这样如果这一打文件被抽走、增加、替换了一页,这个印章都不会残缺了。

密钥协商

后面说了出于性能的思考,咱们个别只用非对称加密算法加密一个对称加密密钥,而后再用这个对称加密密钥去真正的加密音讯。这种形式生成的密钥不够随机,只有通信的发送方参加了密钥的生成。密钥协商算法能够使通信的单方独特参加协商出一个密钥。

咱们同样能够假如这是一个只会算乘法的世界,而后通信的单方能够当时约定好一个数字(例如 10),而后单方都再随机生成一个谁都不晓得的数字(例如单方别离是 2 和 3),而后单方都用本人随机生成的数字乘以约定好的数字发给对方(10 * 2 = 2010 * 3 = 30),单方收到后再都用收到的数字乘以本人随机生成的数字(30 * 2 = 6020 * 3 = 60)就失去了雷同的数字(60)作为密钥。最终生成的这个密钥单方都有参加,而其他人就算拿到了两头传递的 102030 等信息,但因为他们都不会计算除法,就没方法晓得真正的密钥是什么。

这种密钥协商算法能够平安的替换一个密钥,但没方法避免中间人攻打,所以个别应用时还须要联合数字签名等应用。

非对称加密算法概览

非对称加密算法的品种比拟多,而且不像对称加密算法中 AES 一枝独秀,各种算法都有其应用场景,因而别离简略介绍一下。

依赖大数合成问题的算法:

  • RSA 算法是非对称加密算法中最支流、应用范畴最广、兼容性最好的。安全性随着其密钥长度的减少而减少,但性能也会随之急剧下降。

依赖离散对数问题的算法:

  • DSA (Digital Signature Algorithm) 算法顾名思义,他在设计上就只是用来签名的,不能用来加密。因为平安问题曾经不举荐应用了。
  • DH 密钥协商算法 / 协定,能够在通信的单方之间平安的替换会话密钥。

依赖椭圆曲线问题的概念:

  • ECC(Elliptic Curve Cryptography,椭圆曲线算法),比 RSA、DSA 等依赖大数合成和离散对数的算法性能更好。等同安全级别须要的密钥长度也更短。ECC 是一个泛指,并不是一个具体的算法。
  • ECDSA 是应用椭圆曲线实现的 DSA 算法的变体,具备比 DSA 算法更高的安全性和更好的性能。
  • EdDSA 和 ECDSA 相似,但应用的是爱德华兹曲线,比 ECDSA 性能和安全性更好。
  • ECDH 是应用椭圆曲线实现的 DH 密钥替换算法。

ECDSA、EdDSA、ECDH 和 ECC 一样,都是一种泛指,要联合具体的椭圆曲线实现。

具体的椭圆曲线:

  • NIST P-256/P-384/P-512 曲线。
  • Curve25519 曲线,性能比 P 系列曲线更好,而且 NIST 的曲线被人狐疑可能会有后门,而 Curve25519 更加公开通明。

具体的椭圆曲线算法:

  • X25519 是应用了 Curve25519 曲线的 ECDH 算法实现。
  • Ed25519 是应用了 Curve25519 曲线和 SHA-512 的 EdDSA 算法实现。

非对称加密算法比照

这么多非对称加密算法,抛开不同凡响的 DH 算法和曾经不再举荐应用的 DSA 算法,其实剩下的次要就是依赖大数合成问题的 RSA 算法和依赖椭圆曲线问题的 ECC 系列算法了。

更具体一点,咱们能够比照一下 Curve25519 和 3072 位的 RSA 算法。

在平安方面,Curve25519 的密钥长度是 256 位,和 3072 位的 RSA 算法一样,都大略等同于 128 位的密钥强度。所以他们从安全性上来讲,基本上是雷同的。

在性能方面,ECC 算法所需的密钥长度更短、计算性能更快。而且随着对安全级别要求的晋升,ECC 的密钥长度是线性减少的、而 RSA 并不是。例如要实现 256 位的密钥强度,ECC 只须要 256 位密钥长度,RSA 算法则须要 15360 位。所以普遍认为 ECC 将会取代 RSA 算法。

但这并不意味着 RSA 算法在当初就曾经过期了。RSA 算法更加久经考验,适用范围和兼容性更好。满足以后平安强度所需的密钥长度还在可承受范畴内,只是性能差了点。

密钥强度

密钥强度是指暴力破解所需的计算复杂度,通常用位来示意。

对于对称加密算法来说,密钥强度比拟间接。例如 AES-128 算法的密钥强度就是 128 位。因为对称加密算法暴力破解的形式就是把所有的密钥可能都试一遍,没有更好的办法了。

而非对称加密算法暴力破解则能够依据一些数学个性有更高效的破解办法,所以密钥强度并不等同于其密钥长度。例如 3072 位的 RSA 算法和 256 多位的椭圆曲线算法都大略只有 128 位的密钥强度。也就是说要破解 3072 位的 RSA 算法,并不需要计算 2^3072 次,只须要计算 2^128 次就够了。

具体密钥强度的对应关系,以及不同算法举荐应用的密钥长度能够参考 Keylength – NIST Report on Cryptographic Key Length and Cryptoperiod (2020)。

退出移动版