一、前言

在数字信息时代,数据的安全性和隐私保护成为了至关重要的问题。随着信息技术的迅猛发展和互联网的普及,各种网络攻击和数据泄露事件屡见不鲜,给个人和企业都带来了很大的威胁。加密技术作为保护数据安全的重要手段,越来越受到重视。

加密算法是指将敏感信息转化为不可读形式的数学方法,包括对称加密算法和非对称加密算法等。这些算法被广泛应用于各种场景,如在线支付、电子邮件、文件传输等,以确保数据在传输和存储过程中的安全性和完整性。

本文将介绍几种常用的加密算法,理解它们的工作原理、优缺点以及应用场景。希望通过这篇博客,能够为大家提供一些有用的信息,帮助在实际应用中选择合适的加密技术来保护数据安全。

二、常用的加密算法

2.1、对称加密算法

  1. AES(Advanced Encryption Standard)

    • 简介AES是一种对称加密算法,广泛应用于各类数据加密场景。
    • 密钥长度128位、192位、256位。
    • 优点:安全性高、性能好,被广泛认为是目前最安全的对称加密算法之一。
  2. DES(Data Encryption Standard)

    • 简介DES曾是广泛使用的对称加密算法,但由于密钥长度较短(56位),现已被认为不够安全。
    • 密钥长度:56位。
    • 优点:历史悠久,曾经被广泛使用。
  3. 3DES(Triple DES)

    • 简介3DES是对DES算法的扩展,通过三次加密提高安全性。
    • 密钥长度112位或168位。
    • 优点:比DES更安全,但性能较差。

2.2、非对称加密算法

  1. RSA(Rivest-Shamir-Adleman)

    • 简介RSA是一种非对称加密算法,广泛应用于数据加密和数字签名。
    • 密钥长度1024位、2048位、4096位等。
    • 优点:安全性高,适用于加密少量数据和密钥交换。
  2. ECC(Elliptic Curve Cryptography)

    • 简介ECC是一种基于椭圆曲线数学的非对称加密算法,提供相同安全级别的情况下,密钥长度更短。
    • 密钥长度160位、224位、256位等。
    • 优点:高效且安全,适用于资源受限的环境。

2.3、哈希算法

  1. SHA-256(Secure Hash Algorithm 256-bit)

    • 简介SHA-256是一种广泛使用的哈希算法,生成256位的哈希值。
    • 优点:安全性高,广泛应用于数字签名和区块链技术。
  2. MD5(Message Digest Algorithm 5)

    • 简介MD5是一种常用的哈希算法,生成128位的哈希值。
    • 优点:计算速度快,但已被证明存在安全漏洞,不推荐用于安全性要求高的场景。
  3. SHA-1(Secure Hash Algorithm 1)

    • 简介SHA-1生成160位的哈希值,曾经广泛使用,但已被认为不够安全。
    • 优点:曾经广泛使用,但现在被认为不安全。

加密哈希算法

  1. HMAC(Hash-based Message Authentication Code)
    • 简介HMAC是一种基于哈希函数和密钥的消息认证码,用于验证消息的完整性和真实性。
    • 优点:结合了哈希算法和密钥,提供了较高的安全性。

三、对称加密算法 - AES

AESAdvanced Encryption Standard,高级加密标准)是一种对称加密算法,用于加密和解密数据。它由美国国家标准与技术研究院(NIST)于2001年发布,取代了之前的DES(Data Encryption Standard)算法,成为新的加密标准。AES广泛应用于各种安全通信和数据保护场景,包括网络通信、文件加密、硬盘加密等。

主要特点:

  1. 对称加密AES是一种对称加密算法,这意味着加密和解密使用相同的密钥。
  2. 分组加密AES是一种分组加密算法,处理固定长度的数据块(128位,即16字节)。
  3. 多种密钥长度AES支持128位192位256位的密钥长度,提供不同级别的安全性。
  4. 高效性AES设计高效,适合在硬件和软件中实现,具有较高的加密和解密速度。

粗略加密流程:

image.png

放大看AES里面的加密过程:

image.png

3.1、Initial round

初始轮AddRoundKey操作是AES加密的第一步,AddRoundKey主要的工作就是把矩阵中的每一个字节都与该次回合密钥(round key)做XOR运算;AddRoundKey用的密钥依赖密钥扩展

image.png

3.2、字节代换(SubBytes)

字节代换(SubBytes)通过使用一个固定的S-BoxSubstitution box)对状态矩阵中的每个字节进行替换,从而引入非线性变换,增加加密的复杂性和安全性。

S-Box通常是固定的(例如DESAES加密算法), 也有一些加密算法的S-Box是基于密钥动态生成的(例如Blowfish双鱼算法加密算法)。

image.png

3.3、⾏移位(ShiftRows)

image.png

3.4、列混合(MixColumn)

MixColumns操作的主要作用是将状态矩阵中的每一列视为一个多项式,并在有限域GF(2^8)上与一个固定的多项式矩阵相乘。这一步骤通过混合列内的字节,增加了数据的扩散性,使得单个字节的变化能够影响整个数据块。

image.png

image.png

举例:

c‘0 = 02*d4 ⊕ 03*bf ⊕ 01*5d ⊕ 01*30

这里乘法不是普通意义上的乘法,而是有限域 GF(2^8) 上的乘法。在有限域GF(2^8)上,乘法是通过以下步骤进行的:

  1. 左移操作:将数值左移一位,相当于乘以2
  2. 模约减:如果左移操作导致数值超过一个字节(即结果大于0xFF),则需要模约减(模多项式为0x11B)。模约减是通过按位异或0x11B来实现的。

详细计算过程:

  1. 左移操作

    0xd4 = 11010100 (二进制)
    0xd4 << 1 = 110101000 (二进制) = 0x1A8 (十六进制)
    
  2. 模约减

    0x1A8 = 110101000 (二进制)
    0x11B = 100011011 (二进制)
    0x1A8 XOR 0x11B = 110101000 XOR 100011011 = 010110101 (二进制) = 0xB5 (十六进制)
    

3.5、密钥扩展(Key Expansion)

AES128AES192AES256,分别会使用AddRoundKey加密111315轮,每轮需要用16字节的密钥,所以AES128AES192AES256分别需要11*16=17613*16=20815*16=240字节的密钥。

AES128举例,第一轮AddRoundKey16Byte的密钥,全部来自用户的输入(密钥长度是128bit),假设需要用用到的所有密钥是一个长度为44Word(一个Word大小4个字节)数组 W[i],i的范围是0~43。后面每一轮用到的密钥计算方式如下:

  1. 如果i不是4的倍数(即 i%4 != 0)则计算方式:W[i] = W[i-4] ⨁ W[i-1]
    image.png
  2. 如果i4的倍数(即 i%4 == 0),则:W[i]=W[i-4]⨁T(W[i-1])
    • 函数T3部分组成:字循环、字节代换和轮常量异或。
    • RotWord:对字进行循环左移一个字节。
      image.png
    • SubWord:对字的每个字节应用S盒Substitution box)变换。
      image.png
    • Rcon:轮常量(Round Constant),是一个特定的常量数组。
      image.png

3.6、加密模式

ECB(Electronic Codebook)

  • 工作原理:每个数据块独立加密。
  • 优点:实现简单,适合加密少量数据。
  • 缺点:相同的明文块加密后会产生相同的密文块,容易被攻击者利用模式识别攻击。
  • 应用场景:由于安全性较差,通常不推荐在实际应用中使用。

image.png

CBC(Cipher Block Chaining)

  • 工作原理:每个明文块在加密前先与前一个密文块进行XOR操作,第一个块与初始化向量(IV)进行XOR
  • 优点:相同的明文块不会产生相同的密文块,增强了安全性。
  • 缺点:加密是串行的,不能并行处理;解密可以并行处理
  • 应用场景:常用于文件加密和数据传输。

加密过程:
image.png

解密过程:
image.png

CFB(Cipher Feedback)

  • 工作原理:将前一个密文块加密后,再与当前明文块进行XOR操作生成当前密文块。
  • 优点:可以处理任意长度的数据,适合流式数据加密。
  • 缺点:加密和解密都是串行的,不能并行处理。
  • 应用场景:适用于流数据加密,如网络通信。

加密过程:
image.png
解密过程:
image.png

OFB(Output Feedback)

  • 工作原理:将前一个加密输出作为下一个块的输入,与当前明文块进行XOR操作生成当前密文块。
  • 优点:类似于流密码,可以处理任意长度的数据;加密和解密可以并行处理。
  • 缺点:对IV非常敏感,IV的重复会导致安全问题。
  • 应用场景:适用于流数据加密和同步数据加密。

加密过程:
image.png
解密过程:
image.png

CTR(Counter)

  • 工作原理:使用一个计数器值加密,与明文块进行XOR操作生成密文块。计数器值通常是一个不断增加的数值。
  • 优点:可以并行处理加密和解密操作,效率高;可以随机访问加密数据。
  • 缺点:对计数器的管理要求严格,计数器值不能重复。
  • 应用场景:适用于高性能要求的场景,如磁盘加密、网络数据加密。

加密过程:
image.png
解密过程:
image.png

GCM(Galois/Counter Mode)

  1. 加密和认证GCM模式不仅加密数据,还生成一个消息认证码(MAC),用于验证数据的完整性和真实性。
  2. 并行处理GCM模式支持并行处理,能够提高加密和解密的效率。
  3. 计数器模式GCM模式基于计数器模式(CTR),每个数据块使用一个唯一的计数器值进行加密。
  4. Galois消息认证码GCM模式使用Galois域上的乘法运算生成消息认证码(GMAC),确保数据的完整性和真实性

工作原理

GCM模式的工作流程可以分为两个主要部分:加密和认证。

加密过程:

  1. 初始化向量(IV):选择一个随机的初始化向量(IV)。
  2. 计数器初始化:将IV和一个计数器值(通常为1)结合,生成初始计数器值。
  3. 计数器加密:对初始计数器值进行AES加密,生成一个密钥流。
  4. 块加密:将密钥流与明文块进行XOR操作,生成密文块。
  5. 计数器递增:每加密一个块,计数器递增1

认证过程:

  1. 附加数据GCM模式允许附加数据(AAD),这些数据不被加密,但需要认证。
  2. 生成认证标签:使用Galois域上的乘法运算,结合密文块和附加数据,生成一个消息认证码(MAC)。
  3. 附加认证标签:将生成的认证标签附加到密文后,形成最终的加密输出。

解密过程:

  1. 计数器初始化:与加密过程相同,使用IV和初始计数器值。
  2. 计数器加密:对初始计数器值进行AES加密,生成密钥流。
  3. 块解密:将密钥流与密文块进行XOR操作,恢复明文块。
  4. 计数器递增:每解密一个块,计数器递增1
  5. 验证认证标签:使用Galois域上的乘法运算,结合密文块和附加数据,验证消息认证码(MAC)。

加密过程:
image.png
解密过程:
image.png

3.7、填充模式

在使用AES(Advanced Encryption Standard)加密算法时,加密的数据块大小必须是固定的128位(16字节)。然而,实际应用中待加密的数据长度通常不是16字节的整数倍,因此需要填充(Padding)机制来确保数据块的长度符合要求。

PKCS#7 填充

PKCS#7是最常见的填充方式之一,广泛应用于各种加密标准中。

  • 填充方法:在数据的末尾添加N个字节,每个字节的值都是N,其中N是需要填充的字节数。
  • 示例
    • 如果数据长度为14字节,需要填充2字节,填充值为0x02
    • 原始数据:[0x01, 0x02, ..., 0x0E]
    • 填充后数据:[0x01, 0x02, ..., 0x0E, 0x02, 0x02]

ANSI X.923 填充

ANSI X.923填充方式在数据末尾添加零字节,最后一个字节是填充的字节数。

  • 填充方法:在数据的末尾添加N-1个零字节,最后一个字节的值是N,其中N是需要填充的字节数。
  • 示例
    • 如果数据长度为14字节,需要填充2字节。
    • 原始数据:[0x01, 0x02, ..., 0x0E]
    • 填充后数据:[0x01, 0x02, ..., 0x0E, 0x00, 0x02]

ISO/IEC 7816-4 填充

ISO/IEC 7816-4填充方式在数据末尾添加一个0x80字节,然后添加零字节,直到数据块长度为16字节。

  • 填充方法:在数据的末尾添加一个0x80字节,然后添加零字节,直到数据块长度为16字节。
  • 示例
    • 如果数据长度为14字节,需要填充2字节。
    • 原始数据:[0x01, 0x02, ..., 0x0E]
    • 填充后数据:[0x01, 0x02, ..., 0x0E, 0x80, 0x00]

Zero Padding(零填充)

Zero Padding在数据末尾添加零字节,直到数据块长度为16字节。

  • 填充方法:在数据的末尾添加零字节,直到数据块长度为16字节。
  • 示例
    • 如果数据长度为14字节,需要填充2字节。
    • 原始数据:[0x01, 0x02, ..., 0x0E]
    • 填充后数据:[0x01, 0x02, ..., 0x0E, 0x00, 0x00]
  • 注意:这种填充方式在解密时可能存在歧义,因为无法区分原始数据末尾的零字节和填充的零字节。

image.png

四、非对称加密算法 - RSA

RSA(Rivest-Shamir-Adleman)是一种广泛使用的非对称加密算法,由Ron RivestAdi ShamirLeonard Adleman1977年共同设计。RSA算法基于大整数分解的数学难题,其安全性依赖于大数分解的计算复杂性。RSA算法用于数据加密和数字签名,广泛应用于网络安全、电子商务和数字证书等领域。

4.1、基础知识

质数:是指在⼤于1的⾃然数中,除了1和它本身以外不再有其他因数的⾃然数。
互质:是公约数只有1的两个整数,叫做互质整数。

欧拉函数

  • 欧拉函数(Euler's Totient Function),通常记作φ(n),是数论中的一个重要函数。对于一个正整数nφ(n)表示小于n且与n互质的正整数的个数。这里,两个数互质的意思是它们的最大公约数(GCD)为1
  • 对于两个互质数mn,如果mn互质,则欧拉函数满足乘法性质:φ(mn) = φ(m) * φ(n)
    • φ(6)1,2,3,4,5,6中只有156互质的,所以φ(6) = 2
    • φ(7) 因为 7是质数,只能被自己和1整除,所以φ(7) = 6

同余符号:()是数学中的同余符号,表示两个数在模运算下是同余的。具体来说,对于整数ab和正整数n,如果ab除以n的余数相同,则称ab在模n下是同余的,记作:a ≡ b (mod n) 也等同于 a - b = knk是一个整数。举例:

  • 17 ≡ 5 (mod 12)
  • 23 ≡ 2 (mod 7)

同余的性质

  1. 自反性:对于任意整数a和正整数n,有a ≡ a (mod n)
  2. 对称性:如果a ≡ b (mod n),则b ≡ a (mod n)
  3. 传递性:如果a ≡ b (mod n)b ≡ c (mod n),则a ≡ c (mod n)
  4. 加法:如果a ≡ b (mod n)c ≡ d (mod n),则a+c ≡ b+d (mod n)
  5. 减法:如果a ≡ b (mod n)c ≡ d (mod n),则a-c ≡ b-d (mod n)
  6. 乘法:如果a ≡ b (mod n)b ≡ c (mod n),则a*c ≡ b*d (mod n)

模运算

  1. 加法模运算(a+b) mod n = ((a mod n) + (b mod n)) mod n
  2. 减法模运算(a-b) mod n = ((a mod n) - (b mod n) + n) mod n
  3. 乘法模运算(a * b) mod n = ((a mod n) * (b mod n) ) mod n
  4. 指数模运算:(ab) mod n = ((a mod n)b) mod n

欧拉定理

image.png

等同 aφ(m) - 1 = km

模反元素:
模反元素(Modular Inverse)是数论中的一个概念,通常用于解决模运算中的方程。对于给定的整数a和模数m,模反元素是指一个整数x,使得: a*x ≡ 1 (mod m),等同于 a*x - 1 = k*m
模反元素x存在的条件是am互质,即最大公约数gcd(a,m)=1 。如果am不是互质的,则a在模m下没有模反元素。

4.2、加解密流程

RSA算法包括密钥生成、加密和解密三个主要步骤。以下是RSA算法的详细原理和操作步骤。

步骤 说明 描述
1 选择一对不相等且足够大的质数 p, q
2 计算 p, q 的乘积 n = p * q
3 计算 n 的欧拉函数 φ(n) = (p - 1) * (q - 1)
4 选一个与 φ(n) 互质的整数 e 1 < e < φ(n)
5 计算出 e 对于 φ(n) 的模反元素 d e*d ≡ 1 (mod φ(n))=> ed mod φ(n) = 1
6 公钥 KU = (e, n)
7 私钥 KR = (d, n)
8 将明文 M 加密 Me mod n = C
9 将密⽂ C 解密 Cd mod n = M

举例

  1. 假设 p = 3 、 q = 7 ,n = 21
  2. φ(n) = (q-1)(p-1) = 12
  3. 公钥 e 要满足 1 < e < φ(n) ,随机选择 e = 5
  4. 私钥 d 满足 e*d ≡ 1 (mod φ(n)),所以 d * 5 ≡ 1 (mod 12),根据扩展欧几里得算法算的 d =5
  5. 所以公钥就是 (e, n) = (5,21)
  6. 私钥就是 (d, n) = (5,21)
  7. 假设明文是 10,使用公钥加密 C = C = 105 mod 21 = 19
  8. 解密过程, M = 195 mod 21 = 2476099 mod 21 = 10

4.3、解密推导过程

已知 Me mod n = C,求 Cd mod n = M 是否成立?

解:

  • 先把 Me mod n = C 带入到 Cd mod n = M
  • 可以得到(Me mod n)d mod n = M
  • 根据模运算的性质,我们可以将其进一步简化
  • Med mod n = M
  • ed mod φ(n) = 1 , 所以有 ed = 1 + k*φ(n)
  • 代入 Med mod n = M
  • 得 M1 + k*φ(n) mod n = M
  • M * (Mφ(n))k mod n = M
  • 根据乘法模运算得 ( (M mod n) * ((Mφ(n))k mod n) ) mod n = M
  • M 是一个明文,比如 ASCII 256, 由于 p, q 都是一个很大的质数,所以 n 也是一个远大于 M 的数据。
  • 所以只用证明 (Mφ(n))k mod n = 1 就行了
  • 根据指数模运算得 (Mφ(n))k mod n = (Mφ(n) mod n )k mod n
  • M < p and M < q and n = pq 的话,那 M 就一定跟 n 互质了
  • 根据欧拉定理我们知道,M 和 n 互质的话就有: Mφ(n) ≡ 1 (mod n)
  • 所以 Mφ(n) mod n = 1
  • 所以 (1)k = 1
  • 所以 (Mφ(n))k mod n = 1

五、哈希算法

哈希函数(Hash Function)是一种算法,它将任意长度的输入数据(通常称为消息)转换为固定长度的输出数据(通常称为哈希值或摘要)。哈希函数在计算机科学和密码学中有广泛的应用,主要用于数据完整性验证、数字签名、加密、数据检索等。

哈希函数的特点

  1. 固定长度输出:无论输入数据的长度是多少,哈希函数都生成固定长度的输出。例如,SHA-256总是生成256位(32字节)的哈希值。
  2. 快速计算:哈希函数的计算应该是快速高效的,能够在短时间内处理大量数据。
  3. 不可逆性:哈希函数应具有单向性,即很难从哈希值反推出原始输入数据。
  4. 抗碰撞性:不同的输入数据应该生成不同的哈希值,找到两个不同的输入数据具有相同哈希值的可能性应该非常低。
  5. 雪崩效应:输入数据的微小变化(如改变一个比特)应导致输出哈希值的显著变化。

哈希函数的应用

  1. 数据完整性验证:哈希函数用于验证数据在传输或存储过程中是否被篡改。例如,文件下载后可以通过计算哈希值与提供的哈希值进行比较,验证文件的完整性。
  2. 数字签名:在数字签名中,哈希函数用于生成消息的摘要,签名者对摘要进行签名,接收者可以验证签名的真实性和消息的完整性。
  3. 密码学:哈希函数在密码学中用于生成密钥、密码存储等。例如,用户密码通常通过哈希函数处理后存储在数据库中,以提高安全性。
  4. 数据检索:哈希函数用于快速数据检索和查找,如哈希表(Hash Table)和哈希集合(Hash Set)。
  5. 区块链:在区块链技术中,哈希函数用于生成区块的哈希值,确保区块链的安全性和不可篡改性。

常见的哈希函数

  1. MD5(Message Digest Algorithm 5):生成128位(16字节)的哈希值,已被证明存在安全漏洞,不推荐用于安全性要求高的场景。
  2. SHA-1(Secure Hash Algorithm 1):生成160位(20字节)的哈希值,1995年发布,SHA-1在许多安全协议中广为使用,包括TLSGnuPGSSHS/MIMEIPsec,是MD5的后继者。但SHA-1的安全性在2010年以后已经不被大多数的加密场景所接受。2017年荷兰密码学研究小组CWIGoogle正式宣布攻破了SHA-1[1]
  3. SHA-2(Secure Hash Algorithm 2)2001年发布,包括SHA-224SHA-256SHA-384SHA-512SHA-512/224SHA-512/256SHA-2目前没有出现明显的弱点。虽然至今尚未出现对SHA-2有效的攻击,但它的算法跟SHA-1基本上仍然相似。
  4. SHA-3(Secure Hash Algorithm 3):基于Keccak算法设计,提供更高的安全性,适用于高安全性需求的应用。2015年正式发布,由于对MD5出现成功的破解,以及对SHA-0SHA-1出现理论上破解的方法,NIST感觉需要一个与之前算法不同的,可替换的加密散列算法,也就是现在的SHA-3

5.1、MD5

MD5(Message Digest Algorithm 5)是一种广泛使用的哈希函数,用于生成数据的128位(16字节)哈希值。尽管MD5已经被证明存在安全漏洞,不再适合用于安全性要求高的场景,但它在数据完整性验证等领域仍然有一定的应用。以下是MD5算法的工作原理和操作步骤。

  1. 消息填充

消息填充的目的是使消息的长度满足特定条件,即长度模512等于448。这是为了确保消息长度(以位为单位)加上填充后的长度是512的倍数。

  • 添加一个’1’位:在消息末尾添加一个'1'位(即0x80)。
  • 填充’0’位:在'1'位之后添加足够的'0'位,使得消息长度模512等于448
  • 附加消息长度:在填充后的消息末尾附加消息的原始长度(以位为单位),长度为64位。
  1. 初始化MD缓冲区

MD5算法使用四个32位的寄存器(A、B、C、D)作为缓冲区,并将其初始化为特定的常量:

A = 0x67452301
B = 0xefcdab89
C = 0x98badcfe
D = 0x10325476
  1. 处理消息块

消息被分成512位(64字节)的块,每个块进一步划分为1632位的子块。MD5算法对每个512位的消息块进行四轮变换,每轮包括16次操作。每次操作使用一个非线性函数、一个常量和当前消息块中的一个子块。

  • 四个非线性函数

    • F(X, Y, Z) = (X & Y) | (~X & Z)
    • G(X, Y, Z) = (X & Z) | (Y & ~Z)
    • H(X, Y, Z) = X ^ Y ^ Z
    • I(X, Y, Z) = Y ^ (X | ~Z)
  • 每轮变换

    1. 第一轮:使用函数F和消息块中的子块。
    2. 第二轮:使用函数G和消息块中的子块。
    3. 第三轮:使用函数H和消息块中的子块。
    4. 第四轮:使用函数I和消息块中的子块。

每轮变换包括以下步骤:

  • 将当前的缓冲区值(A、B、C、D)与非线性函数的结果、消息块中的一个子块和一个常量进行加法运算。
  • 将结果进行左循环移位。
  • 将移位后的结果加到当前缓冲区值上。
  1. 输出最终哈希值

所有消息块处理完毕后,缓冲区中的四个寄存器(A、B、C、D)包含了最终的哈希值。将这四个寄存器按小端序连接起来,得到128位的哈希值。

以下是MD5算法的详细计算过程:

  1. 消息填充

    • 假设原始消息长度为L位。
    • 在消息末尾添加一个'1'位(即0x80)。
    • 添加k'0'位,使得L + 1 + k ≡ 448 (mod 512)
    • 在填充后的消息末尾附加消息的原始长度L,长度为64位。
  2. 初始化MD缓冲区

    • A = 0x67452301
    • B = 0xefcdab89
    • C = 0x98badcfe
    • D = 0x10325476
  3. 处理消息块

    • 将消息分成若干个512位(64字节)的块,每个块进一步划分为1632位的子块。
    • 对每个消息块,执行四轮变换,每轮包括16次操作。
  4. 四轮变换

    • 第一轮:使用函数F和消息块中的子块。
    • 第二轮:使用函数G和消息块中的子块。
    • 第三轮:使用函数H和消息块中的子块。
    • 第四轮:使用函数I和消息块中的子块。

image.png

伪代码:

//Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating
var int[64] r, k

//r specifies the per-round shift amounts
r[ 0..15]:= {7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22} 
r[16..31]:= {5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20}
r[32..47]:= {4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23}
r[48..63]:= {6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21}

//Use binary integer part of the sines of integers as constants:
for i from 0 to 63
    k[i] := floor(abs(sin(i + 1)) × 2^32)

//Initialize variables:
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h2 := 0x98BADCFE
var int h3 := 0x10325476

//Pre-processing:
append "1" bit to message
append "0" bits until message length in bits ≡ 448 (mod 512)
append bit length of message as 64-bit little-endian integer to message

//Process the message in successive 512-bit chunks:
for each 512-bit chunk of message
    break chunk into sixteen 32-bit little-endian words w[i], 0 ≤ i ≤ 15

    //Initialize hash value for this chunk:
    var int a := h0
    var int b := h1
    var int c := h2
    var int d := h3

    //Main loop:
    for i from 0 to 63
        if 0 ≤ i ≤ 15 then
            f := (b and c) or ((not b) and d)
            g := i
        else if 16 ≤ i ≤ 31
            f := (d and b) or ((not d) and c)
            g := (5×i + 1) mod 16
        else if 32 ≤ i ≤ 47
            f := b xor c xor d
            g := (3×i + 5) mod 16
        else if 48 ≤ i ≤ 63
            f := c xor (b or (not d))
            g := (7×i) mod 16
 
        temp := d
        d := c
        c := b
        b := leftrotate((a + f + k[i] + w[g]),r[i]) + b
        a := temp
    Next i
    //Add this chunk's hash to result so far:
    h0 := h0 + a
    h1 := h1 + b 
    h2 := h2 + c
    h3 := h3 + d
End ForEach
var int digest := h0 append h1 append h2 append h3 //(expressed as little-endian)

5.2、SHA-256

SHA-256(Secure Hash Algorithm 256-bit)SHA-2(Secure Hash Algorithm 2)家族中的一种哈希函数,广泛应用于密码学、数据完整性验证和数字签名等领域。SHA-256将任意长度的输入数据转换为固定长度的256位(32字节)哈希值。以下是SHA-256算法的工作原理和具体步骤。

SHA-256 算法原理

SHA-256通过一系列的位操作、逻辑运算和非线性函数,将输入数据转换为固定长度的哈希值。其主要步骤包括消息填充、初始化哈希值、消息分块处理和输出最终的哈希值。

  1. 消息填充

消息填充的目的是使消息的长度满足特定条件,即长度模512等于448。这是为了确保消息长度(以位为单位)加上填充后的长度是512的倍数。

  • 添加一个’1’位:在消息末尾添加一个'1'位(即0x80)。
  • 填充’0’位:在'1'位之后添加足够的'0'位,使得消息长度模512等于448
  • 附加消息长度:在填充后的消息末尾附加消息的原始长度(以位为单位),长度为64位。
  1. 初始化哈希值

SHA-256算法使用832位的寄存器作为初始哈希值,这些寄存器被初始化为特定的常量:

H0 = 0x6a09e667
H1 = 0xbb67ae85
H2 = 0x3c6ef372
H3 = 0xa54ff53a
H4 = 0x510e527f
H5 = 0x9b05688c
H6 = 0x1f83d9ab
H7 = 0x5be0cd19
  1. 处理消息块

消息被分成512位(64字节)的块,每个块进一步划分为1632位的子块。SHA-256算法对每个512位的消息块进行64轮变换,每轮使用一个非线性函数、一个常量和当前消息块中的一个子块。

  • 消息扩展:将1632位的子块扩展为6432位的字。
  • 循环变换:对每个消息块执行64轮变换,每轮使用一个非线性函数、一个常量和当前消息块中的一个字。

image.png

image.png

每一轮都把256位缓冲区的值abcdefgh作为输入,并更新缓冲区的值。每一轮会用到一个32位的值W,该值由当前被处理的512比特的消息分组M导出,导出算法是消息扩展算法。每一轮还将使用附加的常数K,其中 0<t≤64,用来使每轮的运算不同。

  1. 轮函数

SHA-256使用以下非线性函数和常量进行变换:

  • 选择函数(Ch)Ch(x, y, z) = (x AND y) XOR (~x AND z)
  • 多数函数(Maj)Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
  • Σ0函数Σ0(x) = ROTR(2, x) XOR ROTR(13, x) XOR ROTR(22, x)
  • Σ1函数Σ1(x) = ROTR(6, x) XOR ROTR(11, x) XOR ROTR(25, x)
  • σ0函数σ0(x) = ROTR(7, x) XOR ROTR(18, x) XOR SHR(3, x)
  • σ1函数σ1(x) = ROTR(17, x) XOR ROTR(19, x) XOR SHR(10, x)
  1. 常量表(K)

SHA-256使用6432位的常量表,这些常量是前64个素数的立方根的小数部分:

K = [
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    ...
    0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c,
    0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
    0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814,
    0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
    0xc67178f2
]
  1. 轮函数计算

每个轮次的计算如下:

for i in range(64):
    T1 = H + Σ1(E) + Ch(E, F, G) + K[i] + W[i]
    T2 = Σ0(A) + Maj(A, B, C)
    H = G
    G = F
    F = E
    E = D + T1
    D = C
    C = B
    B = A
    A = T1 + T2

image.png

  1. 更新哈希值

每处理完一个消息块后,更新哈希值:

H0 = H0 + A
H1 = H1 + B
H2 = H2 + C
H3 = H3 + D
H4 = H4 + E
H5 = H5 + F
H6 = H6 + G
H7 = H7 + H
  1. 输出最终哈希值

所有消息块处理完毕后,连接832位的寄存器,得到256位的哈希值。

伪代码:

初始化
(以下是前8個質數2..19平方根小數部分的前32位元):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19


初始化每輪用的常數
(前64個質數2..311的立方根小數部分的前32位元):
k[0..63] :=
   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2

預處理:
訊息後接上一個位元'1'
再接上k個'0',其中k為最小的非負整數,使所得的訊息長度(位元數)同余於448(mod 512)
將預處理前訊息的長度(位元數)寫成64位元大端序整數,接在最尾


將訊息分成若干連續段處理,每段512位元:
將訊息分成512位元的分段
for 每段
    將該段再分成十六個32位元的字組,看成大端序的整數w[0..15]


    從該十六個字組,計算多四十八個同樣長度的字組,得到總共六十四個32位元字組:
    for i from 16 to 63
        s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor(w[i-15] rightshift 3)
        s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor(w[i-2] rightshift 10)
        w[i] := w[i-16] + s0 + w[i-7] + s1


    初始化此段的雜湊值:
    a := h0
    b := h1
    c := h2
    d := h3
    e := h4
    f := h5
    g := h6
    h := h7

    主迴圈:
    for i from 0 to 63
        s0 := (a rightrotate 2) xor (a rightrotate 13) xor(a rightrotate 22)
        maj := (a and b) xor (a and c) xor(b and c)
        t2 := s0 + maj
        s1 := (e rightrotate 6) xor (e rightrotate 11) xor(e rightrotate 25)
        ch := (e and f) xor ((not e) and g)
        t1 := h + s1 + ch + k[i] + w[i]
        h := g
        g := f
        f := e
        e := d + t1
        d := c
        c := b
        b := a
        a := t1 + t2
        
    將此段的雜湊值加進總和:
    h0 := h0 + a
    h1 := h1 + b
    h2 := h2 + c
    h3 := h3 + d
    h4 := h4 + e
    h5 := h5 + f
    h6 := h6 + g
    h7 := h7 + h


輸出最總的雜湊值(大端序):
digest = hash = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7

六、benchmarks

2-Figure1-1.png

七、参考文章

Advanced Encryption Standard (AES)

密码之基础篇之ECB_CBC_CFB_OFB加密模式

HMAC | MAC | 基于哈希函数的消息认证码| 消息认证码 |HMAC-MD5

Image authentication for digital image evidence

SHA WIKI

RSA加密过程详解

哈希函数 (SHA256/SHA3-Keccak)