本文分为7个部分,第1部分介绍密码学的基本概念,第2部分讲解常见的对称加密算法,第3部分讲解常见的非对称加密算法,第4部分讲解 数字签名, 第5部分讲解PKI(Public Key Infrastructure),第6部分讲解哈希函数加密,第7部分讲解密码学在区块链里的应用, 最后一部分会讲解随机数。
Part 1 密码学基本概念
1.1 密码学提供的4个基本安全服务
-
Confidentiality(机密性):
对于需要保护的机密信息,避免被没有权限的人获取。 -
Data Integrity(数据完整性):
保证数据从被创造开始,经过传输,直到接收者收到数据,数据的完整性和被创造时候是完全一致的。 -
Authentication(发送者的身份认证):
保证接收者所接收到的数据的确是从经过认证的发送者发送的,确保了数据的真实来源。 -
Non-repudiation(不可抵赖性):
证实数据的确是从某人或者某方创造且发送的,当接收者对数据有争议时,创造者以及发送者无法抵赖。
不同加密方法所能提供的安全服务
1.2 密码学基本概念
-
Plaintext(明文):
在传输过程中需要被保护的数据。 -
Encryption Algorithm(加密算法):
给予明文以及加密密钥,通过数学处理(这里的数学处理就是加密算法)产生密文。 -
Ciphertext(密文):
给予明文以及加密密钥,通过加密算法加密从而产生密文。 -
Decryption Algorithm(解密算法):
给予密文以及解密密钥,通过数学处理(这里的数学处理就是解密算法)还原明文。 -
Encryption Key(加密密钥):
发送者拥有的一个值,结合加密算法以及明文来产生密文。 -
Decryption Key(解密密钥):
接收者拥有的一个值,结合解密算法以及密文来还原明文。
1.3 两种不同的密码系统
- Symmetric Key Encryption(对称加密):
加密与解密过程都使用同样的密钥。
比较常见的对称加密算法有: Digital Encryption Standard(DES), Triple-DES, IDEA, BLOWFISH。
对称加密的挑战:
- 密钥的产生: 由于加解密的过程使用相同的密钥,因此双方需要事先对产生密钥的机制达成共识。
- 信任问题: 双方都要确保密钥只有发送者以及接收者知道,没有泄漏。一旦有第三方知道了密钥,数据的安全性就失效了。
- Asymmetric Key Encryption(非对称加密):
加密与解密过程使用不同的密钥,使用公钥加密,使用私钥解密。
非对称加密的挑战:
- 公钥的真实性: 确保公钥的确是真实的拥有人所有的那个公钥。
比较常见的非对称加密算法有: RSA, ElGamal, ECC。
非对称加密基本模型
1.4 Block Ciphers & Stream Ciphers(分组密码以及流密码)
-
Block Ciphers(分组密码):
明文是通过一块一块的二进制文档执行加密过程形成的密文。 -
Stream Ciphers(流密码):
明文是一个个bit执行加密过程形成的密文。
1.5 Feistel Block Cipher(菲斯特尔结构的块加密算法):
菲斯特尔结构的块加密算法是著名的一个分组密码加密的设计模型。
菲斯特尔结构的块加密算法Part 2 常见的对称加密算法
1.1 Data EncryptionStandard(DES):
-
DES是Feistel密码的一个实现。 使用16轮Feistel结构。 块大小是64位。 虽然密钥长度为64位,但DES的有效密钥长度为56位,因为64位密钥中的8位未被加密算法使用(仅用作校验位):
DES的基本结构 -
初始排列和最终排列是彼此相反的直排列排列(P-box):
排列置换 -
圆函数
DES加密函数的核心。 DES加密函数将48位密钥应用于最右边的32位,以产生32位输出。
圆函数 -
密钥生成
循环密钥生成器从56位密码密钥中创建16个48位密钥。
密钥生成的过程
1.2 Triple DES:
1990年后对DES进行彻底的密钥搜索的速度开始引起DES用户的不适。 然而,用户并不想取代DES,因为它需要花费大量的时间和金钱来改变广泛采用并嵌入到大型安全架构中的加密算法。
务实的做法不是完全放弃DES,而是改变DES的使用方式。 这导致了三重DES(3DES)的修改方案。
三重DES
在使用3TDES之前,用户首先生成并分配一个3TDES密钥K,它由三个不同的DES密钥K1,K2和K3组成。
triple-DES
详细可以看 Triple-DES
1.3 Advanced Encryption Standard(AES):
高级加密标准(Advanced Encryption Standard,AES)是目前比较流行和广泛采用的对称加密算法。 发现至少比三重DES快6倍。
AES的功能如下:
对称密钥对称分组密码
128位数据,128/192/256位密钥
比Triple-DES更强更快
提供完整的规格和设计细节
详细可以看 AES
Part 3 常见的非对称加密算法
1.1 RSA Crytosystem:
这个密码系统是最初的系统之一。 即使在今天,它仍然是最多被使用的密码系统。 该系统由三位学者Ron Rivest,Adi Shamir和Len Adleman发明,因此被称为RSA密码系统。
1. RSA 密钥对生成过程
1.1 生成 RSA 模数 (n)
选择两个很大的质数, p 和 q。
计算 n = p*q。 为了没那么容易被破解,n 至少要是512bits。
1.2 找出导数(e)
数字 e 必须大于1,同时要小于(p - 1)(q - 1)。
数字 e 与 (p - 1)(q - 1)互质。
1.3 形成公钥
(n, e)这一对数字形成RSA的公钥并且公开。
尽管 n 是公钥的一部分,但是由于要在有限时间内把 n 做因式分解是很难做到的,这就是RSA的强大地方。
1.4 形成私钥
私钥d 是通过 计算 p, q 和 e 形成的。
`ed = 1 mod (p - 1)(q - 1)`
下面给出生成RSA密钥对的一个例子(为了便于理解,这里采用的素数p&q值很小,实际上这些值非常高)。
设两个素数为p = 7且q = 13。因此,模数n = pq = 7×13 = 91。
选择 e = 5,这是一个有效的选择,因为没有数字是公因子5和(p - 1)(q - 1)= 6×12 = 72,除了1。
这对数字(n,e) = (91, 5)形成公钥,可以让任何我们希望能够向我们发送加密消息的人使用。
向扩展欧几里德算法输入p = 7,q = 13和e = 5。 输出将是d = 29。
因此,公钥是(91, 5),私钥是(91, 29)。
2. RSA 加密与解密算法
1. RSA加密过程
假设发送者希望发送一些文本消息给公钥为(n,e)的人。然后发件人将明文表示为一系列小于n的数字。
为了加密第一个明文P,它是一个模n的数字。 加密过程是简单的数学步骤:
C = Pe mod n
换句话说,密文C等于明文P乘以自己e次,然后减去模n。 这意味着C也是一个小于n的数字。
回到我们的密钥生成例子,明文P = 10,我们得到密文C:
C = 105 mod 91
- RSA 解密过程
RSA的解密过程也非常简单。 假设公钥对(n,e)的接收者已经收到一个密文C。
Plaintext = Cd(C的d次方) mod n
Plaintext = 8229 mod 91 = 10
1.2 ElGamal Crytosystem:
属于ECC的一种变化。加密的核心理念与RSA相似,也是利用离散对数很难求解。
但与RSA不同的是 公钥的组成部分,EIGamal的公钥有三部分组成, 质模数 p, 生成元素 g, 以及 公共的 Y = gx(g的x次方) mod p。
详细可以看 ElGamal Crytosystem
1.2 Elliptic Curve Cryptography(ECC):
椭圆曲线密码术(ECC)是用来描述一套密码工具和协议的术语,其安全性基于特殊版本的离散对数问题。它不使用数字模p。ECC基于与称为椭圆曲线的数学对象相关联的数字集合。有这些数字的加法和计算倍数的规则,就像数字模p一样。
ECC包含许多最初为模块化数字设计的密码方案的变体,如ElGamal加密和数字签名算法。
相信当应用于椭圆曲线上的点时,离散对数问题更加困难。这会提示从数字模p切换到椭圆曲线上的点。如果我们使用基于椭圆曲线的变体,也可以用较短的密钥获得等效的安全级别。
较短的密钥有两个好处:
易于管理
高效的计算
这些优点使基于椭圆曲线的加密方案变体对计算资源受到限制的应用程序非常有吸引力。
详细可以看 Elliptic Curve Cryptography
Part 4 Digital Signature (数字签名)
1.1 为什么需要数字签名
- 识别篡改(信息内容的篡改)
- 识别伪装(信息来源的确认)
- 防止否认(信息来源身份不可抵赖)
1.2 签名的生成与验证
- 生成签名: 用私钥对信息进行加密 得到密文(数字签名)
- 验证签名: 用对应的公钥对密文(数字签名)进行解密
- 常用方法: 对消息的散列值进行签名
1.3 应用实例
- 安全信息公告
- 公钥证书
- SSL/TLS
1.4 RSA 数字签名
^符号表示为多少次方
签名 = 消息^D mod N (D和N 为签名者的私钥,计算消息的D次方并求mod N,所得余数即为签名)
消息 = 签名^E mod N (E和N 为签名者的公钥,计算签名的E次方并求mod N)
举个例子:
私钥: D = 29; N = 323
公钥: E = 5; N = 323
消息: 123
由于 N 的值为 323, 因此消息需要为 0 ~ 322 这个范围内的整数. 假设需要对 123 这个消息进行签名.
用私钥(D,N) = (29,323) 对消息 123 进行签名.
消息^D mod N = 123^29 mod 323 = 157
因此 (消息, 签名) = (123, 157)
用公钥(E,N) = (5,323)对消息进行验证
签名^E mod N = 157^5 mod 323 = 123
得到消息 123 与发送者发送过来的消息 123 是一致的,因此签名验证成功.
1.5 ECDSA (椭圆曲线数字签名)
https://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/
-
椭圆曲线方程: y^2 = x^3 + ax + b
维尔斯特拉斯标准形式 (Weierstrass normal form) -
椭圆曲线在 实数域 上的方程
image.png -
椭圆曲线在 有限域 上的方程
image.png
整数模p的集合包含所有从 0 到 p - 1的整数。加法和乘法都按模数运算规则去计算。这里有一些F(23)的例子:
加法逆: a在集合中, -a在集合中的定义为使 a + (-a) = 0, 这就是加法逆元运算
乘法逆: a在集合中,且不为0, a^-1 在集合中定位为使 a* a^-1 = 1, 这就是乘法逆元运算
-
加: (18+9) mod 23 = 4
-
减: (7 - 14) mod 23 = 16
-
乘: 4 * 7 mod 23 = 5
-
加法逆元: -5 mod 23 = 18 -> (5 +(-5) ) mod 23 = (5 + 18) mod 23 = 0
-
乘法逆元: 9^-1 mod 23 = 18 -> 9 * 9^-1 mod 23 = 9 * 18 mod 23 = 1
-
有限域上的计算
对详细的数字计算有兴趣可以参考这篇 如何在有限域上做加减乘除运算
https://mp.weixin.qq.com/s/nJkHKSMKdQKvHq9RW6CHkQ
在聊椭圆曲线前,我们先打一些基础然后再讨论一下对数问题.
群(Group)
在一个集合上定义一个二元运算,这就是数学中的群。一个集合 G 要成为一个群,必须满足下面 4 个条件:
- 封闭性(Closure): a,b 被包含于 G, 那么 a+b 也一定是 G 的元素
- 结合律(associativity): (a + b) + c = a + (b + c)
- 存在一个单位元 0(identity element): a + 0 = 0 + a = a
- 每个数都存在一个相反数(inverse): a + b = 0, a = -b
如果我们加上第 5 个条件: - 交换律(commutativity): a + b = b + a
这个群就叫阿贝尔群(Abelian group)
从平常的加法概念来看, 整数集 Z 是一个群(而且是阿贝尔群). 自然数集 N 不是一个群.
椭圆曲线上的群论
我们可以在椭圆曲线上定义一个群:
- 群中的元素就是椭圆曲线上的点
- 单位元就是无穷处的点0
- 相反数P, 是关于X轴对称的另一边的点
- 加法规则定义如下: 取一条直线上的三点 (这条直线和椭圆曲线相交的三点), P, Q, R(皆非零), 他们的总和等于0, P+Q+R=0
椭圆曲线 展示
- 加法
- 假设椭圆曲线上有 P, Q 两个点 经过这两个点做一条直线和椭圆曲线相交于第三点 R 然后做关于 x 轴的对称点 -R, -R 即是 R 的逆元 根据阿贝尔群的定义, -R 也一定在椭圆曲线上
- 定义 P+Q = -R, 也就是说椭圆曲线上任意两点的和也在椭圆曲线上 同样可以引申出椭圆曲线上任意三点的和为 0 即 P+Q+R = 0
- 假如 P=Q, 则作椭圆曲线在 P 点的切线, 与曲线相交于 R, 则 R = P+P = 2P
https://andrea.corbellini.name/ecc/interactive/reals-add.html
椭圆曲线 加法运算.png- 乘法
乘法是由加法的这一条规则产生的
- 假如 P=Q, 则作椭圆曲线在 P 点的切线, 与曲线相交于 R, 则 R = P+P = 2P
如下图: 点 A 的自我相加过程就是做 乘法的过程 这个过程叫 Point Doubling
Point Doubling.png Point Doubling.png- 无穷点 (Point of Infinity)
一条垂直线上的两点相加 结果是 无穷点(用0表示)
因为没有一个第三点与这条垂直线相交 所以我们无法定义这种加法
标量积(Scalar multiplication)
Scalar Multiplication.png计算 nP 需要做 n次加法 如果 n 为 k 位二进制 时间复杂度为 O(2^k)
倍加算法 比如 n = 151 二进制为 10010111
倍加算法.png
image.png
用倍加算法 时间复杂度有了很大的改进 O(logN) or O(k)
对数问题
Q = nP
- 给定 n 和 P, 有了倍加算法 计算 Q = nP 是相对简单的
- 但是如果给定 Q 和 P, 我们怎么去计算 n?
- 对数问题还有其他形式, 当我们把椭圆曲线放在有限域上面来讨论, 这时候对数问题就变成了 离散对数问题
椭圆曲线在有限域上的离散对数问题
-
方程式: y^2 = x^3 + ax + b (mod p) { (4a^3 + 27b^2)!=0 }
-
给定 y^2 = x^3 + 7 这个方程 取模后的图像 (a = 0, b = 7, p = 211)
-
点P(35, 204)
-
点Q(119, 72)
这只是 p = 211, 像 Secp256k1 这条椭圆曲线的 p = 115792089237316195423570985008687907853269984665640564039457584007908834671663 一个78位的数字 要怎么求出 n?
椭圆曲线有限域离散对数问题.png
一个通俗的比喻: 假设这些点是有个人 A 在一个很大的房间里玩弹珠的游戏 玩了两年 两年后 A 的朋友 B来了 B看到了最后的点 以及 A 告诉B 起点 但是B怎么能知道 A 是弹了多少次才从起点弹到终点?
ECC_dots.gif y^2 = x^3 + 7 实数域.png y^2 = x^3 + 7 有限域.png
上面这两张图是 椭圆曲线 - Secp256K1: y^2 = x^3 + 7
第一张图: 定义在 实数域
第二张图: 定义在 有限域Zp
是用下面的参数(p,a,b,G,n,h)形成的:
p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F = 2^256 - 2^32 - 997
a = 0
b = 7
G = [0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798,
0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8]
n = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141
h = 1
-
p: 素数p 用于确定有限域的范围 假设 p = 23, 那么有限域上面的二元运算都会基于 mod 23. (时间, 星期)
-
a,b: 给定的椭圆曲线方程中a与b值 (y^2 = x^3 + ax + b)
-
G: 基点的值 公开给大家知道的值 (Reference Point or Point of Origin)
基点G是如何确定的? 比如 Secp256K1 这条椭圆曲线
- 计算椭圆曲线的阶 N (N, Schoof算法 用来计算椭圆曲线的阶 https://en.wikipedia.org/wiki/Schoof%27s_algorithm)
- 选择一个阶为 n 的子群, n 必须是素数且必须是 N 的因子
- 计算辅因子 h = N/n (拉格朗日定理 h = N/n 这里的 h 永远是一个整数 因为 n 是 N 的因子)
- 在曲线上选择一个随机的点 P
- 计算 G = hP
- 如果 G 为0 回到步骤4, 如果不为0, 我们就找到了阶为 n 和辅因子为 h 的子群的基点.
-
n: 有两个定义
- 这是一个最小的正整数 i 使得基点 G 与 i 相乘(椭圆曲线世界的相乘) 结果会是无穷
- 一个群的阶 也就是说 一个群里面所有的点的数量
如果椭圆曲线上一点P, 存在最小的正整数 n 使得数乘 nP=O∞, 则将 n 称为 P 的阶
阶.png
计算可得 27P = -P = (3, 13) 所以 28P = 0∞ P的阶为28
- h: 子群的辅助因子 h = N/n
N: 椭圆曲线的阶 n: 子群的阶
如何签名?
Sig = F sig ( F keccak256 ( m ) , k )
- k 是私钥
- F keccak256 是哈希函数
- Sig = (r,s) 数字签名的结果 (r,s) 两个值
如何计算 r
- 先计算 r_point (临时公钥), 临时私钥(随机数tp) * 基点G r_point = tp * G
- 指定 point_field, 以Secp256K1的 Order的值为基础的有限域 (也就是上面的 n 参数)
- 最后计算 r 值, point_field mod (r_point.x) 得出 r 值 r_point.x 也就是 1 的 x轴坐标 也就是临时公钥的 x轴坐标
如何计算 s
s ≡ q^-1 (Keccak256(m) + r * k) (mod p)
- q 是临时私钥
- r 是临时公钥的 x轴坐标值
- k 是签名者的私钥
- p 是素数阶
- q^-1 不是 q 的负一次方 而是 q 的逆元
- 计算 (Hash(m) + r * k) (k为私钥, m为数据, Hash是所用哈希函数比如 Keccak256)
- (1) * (2) mod p 得出 s 值
如何验证签名?
- 验证签名的原理就是用签名的结果 (r,s) 以及公钥 去算出椭圆曲线上的一个点 Q. 如果这个点Q的X轴坐标的值与 r 值相等, 就算验证成功了.
- w = s^-1 mod p 对 s 值 在 Secp256k1的有限域上做 乘法逆元运算 求出一个 w 值
- u1 = Keccak256(m) * w mod p
- u2 = r * w mod p
- Q ≡ u1 * G + u2 * K (mod p) 最后算出椭圆曲线上的点Q
- 如果 Q.x = r 验证成功
- r 和 s 是签名的结果值
- K 是签名者的公钥
- G 是椭圆曲线上的基点
- p 是素数阶
P.S. 上述验证签名的过程中 没有用到发送者的 私钥
ECC 和 RSA 对比
RSA 密钥大小(bits) ECC 密钥大小 (bits)
1024 160
2048 224
3072 256
7680 384
15360 521
有一个研究例子 同一台计算能力的计算机
- 破解 228-bit 的 RSA 所消耗的能量可以拿来煮沸一汤匙的水
- 破解 228-bit 的 ECC 所消耗的能量比煮沸整个地球上的水还要多
如何验证一条椭圆曲线的安全性
为什么 比特币和以太坊要选择 Secp256k1 这条椭圆曲线?
- 安全性
- 计算性能
假如有人提供一条椭圆曲线比如 Secp256r1 如何验证这条曲线的安全性?
Part 5 Public Key Infrastructure(PKI):
因为公钥是公开的,很容易被破坏或者篡改,因此需要建立和维持一种可信的基础机制来管理公钥。
密钥的生命周期
PKI由5部分组成:
1.1 Digital Certificate(数字证书):
作为比喻,证书可以被视为发给该人的身份证。人们使用驾照,护照等身份证来证明自己的身份。数字证书在电子世界中具有相同的基本功能。
但有一点不同,数字证书不仅发给人,还可以发给电脑,软件包或任何其他需要证明电子世界身份的东西。
数字证书基于ITU标准X.509,该标准定义了公钥证书和认证验证的标准证书格式。因此数字证书有时也被称为X.509证书。
与用户客户端相关的公钥与证书颁发机构(CA)一起存储在数字证书中,以及其他相关信息,例如客户信息,到期日期,使用情况,发行者等。
CA对此整个信息进行数字签名并在证书中包含数字签名。
任何需要对客户的公共密钥和相关信息进行保证的人,他都会使用CA的公钥进行签名验证过程。成功的验证可确保证书中给出的公钥属于在证书中给出详细信息的人员。
下图了展示了个人/实体获取数字证书的过程:
获取数字证书的过程
如图所示,CA接受来自客户端的申请以证明其公钥。 CA在适当验证客户身份后,向该客户发出数字证书。
1.2 Certifying Authority(CA):
如上所述,CA向客户颁发证书并协助其他用户验证证书。 CA负责正确识别要求颁发证书的客户的身份,并确保证书中包含的信息是正确的并对其进行数字签名。
CA的关键功能:
-
生成密钥对 - CA可以独立或与客户端共同生成密钥对。
-
颁发数字证书 - CA在客户提供证书以确认其身份后颁发证书。 CA随后签署证书以防止修改证书中包含的详细信息。
-
发布证书 - CA需要发布证书,以便用户可以找到证书。有两种方法可以实现这一点。一种是发布相当于电子电话号码簿的证书。另一种是通过某种方式将证书发送给你认为可能需要的人。
-
验证证书 - CA在环境中提供公钥,以协助验证其在客户数字证书上的签名。
-
撤销证书 - 有时,由于某些原因(例如用户违反私钥或在客户端失去信任),CA撤销颁发的证书。撤销后,CA会维护环境可用的所有已撤销证书的列表。
证书类别
有四种典型的证书类别:
第1类 - 通过提供电子邮件地址可轻松获取这些证书。
第2类 - 这些证书要求提供额外的个人信息。
第3类 - 这些证书只有在对请求者的身份进行检查后才能购买。
第4类 - 它们被需要高度信任的政府和金融机构使用。
1.3 Registration Authority(RA):
CA可以使用第三方注册机构(RA)对要求证书确认其身份的人或公司进行必要的检查。 RA可能在客户端看起来像一个CA,但它们实际上并不签署发布的证书。
1.4 Certificate Management System(CMS):
这是发布证书的管理系统,暂时或永久暂停,续订或撤销证书。 证书管理系统通常不会删除证书,因为可能有必要在某个时间点证明其身份,这是出于法律原因。 CA和相关RA运行证书管理系统,以便能够跟踪他们的责任。
1.5 Private Key Tokens
虽然客户端的公钥存储在证书中,但关联的私钥可以存储在密钥所有者的计算机上。 这种方法一般不采用。 如果攻击者能够访问计算机,他可以轻松访问私钥。 出于这个原因,私钥存储在通过密码保护的安全可移动存储令牌上。
不同的供应商经常使用不同的专有的存储格式来存储密钥。 例如,Entrust使用专有的.epf格式,而Verisign,GlobalSign和Baltimore使用标准的.p12格式。
1.6 Hierarchy of CA:
由于拥有庞大的网络和全球通信的要求,所有用户从唯一一个可信的CA获得证书是不切实际的。其次,只有一个CA的可用性可能会导致大的阻碍,如果CA受到影响。
在这种情况下,层次认证模型很受关注,因为它允许在两个通信方与相同CA没有信任关系的环境中使用公钥证书。
根CA位于CA层次结构的顶部,根CA的证书是自签名证书。
直接隶属于根CA(例如,CA1和CA2)的CA具有由根CA签名的CA证书。
层次结构中下级CA(例如,CA5和CA6)下的CA具有由上级下级CA签名的CA证书。
证书颁发机构(CA)层次体现在证书链中。证书链跟踪从层次结构中的分支到层次结构根的证书路径。
下图显示了具有从实体证书到两个从属CA证书(CA6和CA3)到根证书颁发机构CA证书的证书链的CA层次结构:
CA层次结构
验证证书链是确保特定证书链有效,正确签署和可信的过程。 以下过程验证证书链,从提供验证的证书开始 -
一个正在验证其真实性的客户端提供他的证书,通常连同证书链一直到根CA.
验证者获取证书并使用发行者的公钥进行验证。 发行人的公钥在发行人的证书中找到,该证书位于客户证书旁边的链中。
现在,如果已签署发行人证书的较高的CA由验证方信任,则验证成功并在此停止。
否则,发行人证书的验证方式与客户在上述步骤中完成的相似。 此过程将继续进行,直到在其中找到可信的CA,否则它将持续到根CA。
Part 6 哈希加密函数(哈希=散列)
1.1 哈希函数基本概念
哈希函数非常有用,并且出现在几乎所有信息安全应用程序中。
哈希函数是将数字输入值转换为另一个压缩数值的 数学函数。 哈希函数的输入具有任意长度,但输出始终为固定长度。
哈希函数返回的值称为消息摘要或简单的散列值。 下面的图片说明了哈希函数:
哈希函数过程
1.2 散列函数的典型特征:
-
固定长度输出(散列值)
-
哈希函数将任意长度的数据转换为固定长度。 这个过程通常被称为散列数据。
-
散列比输入数据小得多,因此哈希函数有时称为压缩函数。
-
由于散列是较大数据的较小表示,因此它也被称为摘要。
-
具有n位输出的哈希函数被称为n位哈希函数。 流行的哈希函数生成160到512位之间的值。
-
通常对于输入x的任何哈希函数h,h(x)的计算是一个快速操作。
-
计算哈希函数比对称加密快得多。
1.3 哈希函数的属性
为了成为一个有效的加密工具,哈希函数具有以下属性:
-
Preimage Resistant(抗原像攻击):
已知 x in X(数据摘要集合),要找出 y in Y(数据报文集合), 使得 h(y) = x 是困难的,也称为单向性(One-way)。 -
Second Preimage Resistant(第二抗原像攻击):
已知y in Y, 找出另一个 y' in Y, 使得 h(y') = h(y) 是困难的(计算不可行)。同时也称为弱抗碰撞性(Weak Collision Resistant)。 -
Collision-Resistant(抗碰撞性)
找出任意两个不同的 x, x' in X, 使得 h(x) = h(x') 是困难的(计算不可行)。同时也称为强抗碰撞性(Strong Collision-Resistant)
1.4 哈希算法的设计
散列的核心是一个数学函数,该函数在两个固定大小的数据块上运行以创建散列码。 这个哈希函数构成哈希算法的一部分。
每个数据块的大小因算法而异。 通常块大小从128位到512位。 下图演示了哈希函数:
哈希函数
哈希算法涉及上述哈希函数,如分组密码。 每一轮都会输入一个固定的大小,通常是最近消息块和最后一轮输出的组合。
这个过程重复进行多次,以散列整个消息。 哈希算法的示意图如下图所示:
哈希算法
因为第一消息块的散列值变成第二散列操作的输入,其输出改变第三操作的结果,等等。 这种效应被称为散列的雪崩效应。雪崩效应对两个即使是单个数据位也不相同的消息产生明显不同的散列值。理解哈希函数和算法之间的区别。 哈希函数通过对两个固定长度的二进制数据块进行操作来生成哈希码。哈希算法是一个使用哈希函数的过程,指定如何分解消息以及如何将先前消息块的结果链接在一起。
1.5 常见的哈希函数
-
消息摘要(MD)
很多年来,MD5是最流行和广泛使用的哈希函数。MD系列由哈希函数MD2,MD4,MD5和MD6组成。它被采用为Internet标准RFC 1321。它是一个128位散列函数。MD5摘要已被广泛用于软件世界,以保证传输文件的完整性。例如,文件服务器通常会为文件提供预先计算的MD5校验和,以便用户可以将下载的文件的校验和与其进行比较。2004年,MD5发现了碰撞。据报道,使用计算机集群只能在一个小时内成功进行分析攻击。这种碰撞攻击导致MD5受损,因此不再推荐使用。 -
安全哈希函数(SHA)
SHA系列由四种SHA算法组成: SHA-0,SHA-1,SHA-2和SHA-3。虽然来自同一个家庭,但结构不同。原始版本是1993年由美国国家标准与技术研究院(NIST)发布的SHA-0,一种160位散列函数,它几乎没有缺点,并没有变得非常流行。
后来在1995年,SHA-1被设计用于纠正SHA-0的所谓弱点。SHA-1是现有SHA哈希函数中使用最广泛的。它被用于几个广泛使用的应用程序和协议,包括安全套接字层(SSL)安全。
2005年,发现了一种在实际时间框架内发现SHA-1冲突的方法,使SHA-1的长期可用性受到怀疑。
SHA-2系列具有四个更进一步的SHA变体,SHA-224,SHA-256,SHA-384和SHA-512,取决于其散列值中的位数。还没有成功的攻击报道过SHA-2哈希函数。
虽然SHA-2是一个强大的哈希函数。虽然有很大的不同,但其基本设计仍然遵循SHA-1的设计。因此,NIST要求提供新的竞争性散列函数设计。
2012年10月,NIST选择Keccak算法作为新的SHA-3标准。 Keccak提供了许多好处,例如高效的表现和良好的攻击抵抗力。
- RIPEMD
RIPEND是RACE完整性基元评估消息摘要的缩写。这组哈希函数是由开放研究团体设计的,通常称为欧洲哈希函数族。
该集包括RIPEND,RIPEMD-128和RIPEMD-160。此算法还有256位和320位版本。
原始的RIPEMD(128位)基于MD4中使用的设计原则,并且发现提供可疑的安全性。 RIPEMD 128位版本是解决原始RIPEMD漏洞的快速修复替代品。
RIPEMD-160是一个改进版本,是使用最广泛的版本。与RIPEMD-128和RIPEMD-160相比,256和320位版本分别减少了意外冲突的可能性,但没有更高的安全等级。
1.6 哈希函数的常见应用
Merkle Tree 默克尔树
哈希算法的一个重要应用是默克尔树(Merkle tree),默克尔树是一种数据结构,通常是一个二叉树,也有可能是多叉树,它以特定的方式逐层向上计算,直到顶部,最顶层叫做默克尔根(Merkle Root),默克尔树最为常见和最简单的是二叉默克尔树。
- 非叶子节点储存了最底层数据块的哈希值
- 中间节点储存的哈希值是下面两个非叶子节点的共同的哈希值
- Root节点存储的是两个中间节点共同的哈希值
Part 7 区块链里的密码学应用
-
哈希算法
比特币区块链使用的两个哈希函数分别是:1.双重SHA-256,用于完成PoW(工作量证明)。2. RIPEMD160,用于生成比特币地址。
以太坊区块链的PoW使用SHA3的keccak256。 -
Merkle Tree 默克尔树
基于哈希值的二叉树或多叉树,在计算机领域,Merkle Tree用来进行完整性验证处理,在分布式环境下,其进行完整性验证能大量减少数据传输和计算的复杂程度。 -
椭圆曲线算法
比特币中使用基于secp256k1椭圆曲线数学的公钥密码学算法进行签名与验证签名,一方面可以保证用户的账户不被冒名顶替,另一方面保证用户不能否认其所签名的交易。用私钥对交易信息签名,矿工用用户的公钥验证签名,验证通过,则交易信息记账,完成交易。 -
对称加密算法
比特币官方客户端使用AES(对称分组密码算法)加密钱包文件,用户设置密码后,采用用户设置密码通过AES对钱包私钥进行加密,确保客户端私钥的安全。
Part 8 随机数
- 生成随机数的技术一般不太引人注意,但是其实随机数在密码学中扮演非常重要的作用。
比如下面的场景中都会用到随机数:
- 生成密钥
- 生成密钥对
- 生成初始化向量
- 生成Nonce
- 生成盐
- 随机数的三个重要性质
- 随机性 —— 不存在统计学偏差,是完全杂乱的数列 (弱伪随机数)
- 不可预测性 —— 不能从过去的数列推测出下一个出现的数 (强伪随机数)
- 不可重现性 —— 除非将数列本身保存下来,否则不能重现相同的数列 (真随机数)
- 伪随机数生成器的方法
- 线性同余法 Rn+1 = (A * Rn + C) mod M 就是将当前的伪随机数值乘以A再加上C,然后除以M得到的余数作为下一个伪随机数 不可以用于密码技术场景 因为周期短 不具备不可预测性
- 单向散列函数法 单向散列函数的单向性是支撑伪随机数生成器不可预测性的基础
- 密码法 (可以AES RSA) 密码的机密性是支撑伪随机数生成器不可预测性的基础
- 对伪随机数生成器的攻击
- 对种子进行攻击 避免被攻击 一定要使用具备不可重现性的真随机数作为种子
- 对随机数池进行攻击 要保护好随机数池的文件中积累的随机比特序列 (Linux系统中 /dev/random 文件就是一个根据硬件设备驱动的背景噪声储存真随机数的随机数池)
- 反复掷骰子所生成的数列是具备不可重现性的,因为掷骰子所产生的数列无法用公式来表示。所以反复掷骰子所生成的数列具备随机性、不可预测性和不可重现性三种性质。
网友评论