密码算法总结
RC4
RC4
是一种流加密算法,其工作原理可以分为两个主要部分:密钥调度算法KSA
和伪随机生成算法PRGA
。
KSA
密钥调度算法:初始化一个256字节的数组S,S[i] = i。
根据密钥对S进行混排。通过循环交换S数组中的元素,确保密钥影响S的内容。
PRGA
伪随机生成算法:使用KSA生成的S数组,通过循环更新和交换元素生成伪随机字节。
生成的字节与明文进行异或运算,得到密文。
RC4的加密和解密过程相同,因为它是基于与伪随机流的异或运算。
在逆向分析实战中判断RC4
算法的可从其会初始化一个256字节的数组和将一个key
也填充到数组中以及加密函数大概率有两个参数,一个是key
一个是keylen
下面是RC4
算法加/解密过程的C语言代码实现
1 |
|
由于RC4加密具有自反性,所以解密过程与加密过程相同,只需要将密文作为明文,秘钥作为密钥即可
TEA
TEA
在加密的过程中要加密的明文使用2个32位无符号整数(2×4字节),秘钥为4个32位无符号整数(4×4字节),更长的明文可通过分为多个4字节为单位的小组分别进行加密(循环)
在逆向分析实战中判断TEA
算法的可从其3行核心加密中出现的右移4左移5,两行各有3个小括号互相异或的加密流程和单次加密循环32次以及运算中出现的sum
和delta
变量看出
加密流程示意图:
下面是TEA
算法加密过程的C语言代码实现
1 |
|
下面是TEA
算法解密过程的C语言代码实现
1 |
|
魔改TEA的一些方法:
腾讯TEA
TEA的变种,标准TEA中使用的32轮加密,而腾讯只用了16轮。
CBC模式的TEA
将明文分组与前一个密文分组进行异或运算,然后再进行加密,对于第一组的话就设置一个初始值来和第一组明文异或。
每一轮是取v0和v1,data1, data2和v0,v1异或,异或之后的data1和data2传入指针进行tea加密,之后再将加密之后的赋值回的v0和v1。
逆向方法:
1 | void encrypt(uint32_t* v, uint32_t* k) { |
XTEA
在TEA
中,密钥是直接分成4个32位部分(总共128位),每轮加密过程中使用这些部分直接参与计算。密钥在整个加密过程中的使用比较固定,没有变化。这样,攻击者只需要通过分析固定密钥的几轮加密就能发现模式,从而降低了加密算法的安全性。
在XTEA
中,以及密钥并不是每轮加密中直接使用固定的部分。相反,XTEA通过密钥的不同部分在每一轮加密中进行动态调度,密钥在加密过程中会经过多次变换,从而增强了密钥的复杂性和加密过程的不可预测性。
加密流程示意图:
下面是XTEA
算法加密过程的C语言代码实现
1 | void encrypt(uint32_t v[2], uint32_t const key[4]) |
下面是XTEA
算法解密过程的C语言代码实现
1 | void decipher(uint32_t v[2], uint32_t const key[4]) |
XXTEA
XXTEA
使用更复杂的运算方式,它的块大小可以是任意的,密钥也可以是任意长度的(可以不是4的倍数)。
在加密时,XXTEA
会对明文进行分块,然后每个块都会进行加密,加密后的结果再进行拼接,最终形成密文。
在解密时,XXTEA
会对密文进行分块,然后每个块都会进行解密,解密后的结果再进行拼接,最终形成明文。
加密过程示意图:
下面是XXTEA
算法加密过程的C语言代码实现
1 | void xxtea_encrypt(uint32_t *v, int n, uint32_t *key) { |
下面是XXTEA
算法解密过程的C语言代码实现
1 | void xxtea_decrypt(uint32_t *v, int n, uint32_t *key) { |
上文代码中n
代表待加密数据的长度,公式的含义是,对于给定的数据块长度,根据公式计算出加密轮数rounds
,以便在加密过程中执行足够的轮数,达到较高的安全性。
DES
Data Encryption Standard是一种对称密钥加密算法,由IBM公司开发,并于1977年被美国国家标准局采纳为联邦信息处理标准。DES使用56位的密钥和64位的明文分组,通过16轮的Feistel网络进行加密。
DES使用的Feistel网络的结构分为很多个轮(DES为16轮),其中一轮的流程大致为:将输入的64位明文分为长度相等的左右两部分,右半部分直接保留,左半部分由本轮产生的子密钥和右半部分代入轮函数f所得的结果与原左半部分进行异或运算得到,然后将左右两部分交换,进行下一轮加密。其示意图可表示为:
本人用自己的语言总结其算法如下:
在加密时,首先进行一次IP置换,然后即进入Feistel网络,轮函数f的具体过程为先对左半部分进行E置换将其从32位扩展为48位,然后与轮秘钥按位异或,然后分为8组,每组6位,用这六位的首位和末位作为列索引,用剩下4位作为行索引,从对应的S盒中取出对应的值,然后进行P置换,将结果与右半部分进行异或运算,最后将结果与左半部分交换,进行下一轮加密。在最后一轮加密结束后,进行一次逆IP置换得到最终的密文。
而密钥生成过程则是64位密钥先经过PC1置换得到56位秘钥,然后进行循环左移+PC2置换得到48位秘钥,分为16组的子密钥用于16轮加密。
由此可得到完整的DES加密过程。
用C语言的实现可参考以下代码:
1 |
|
用Python的实现可参考:
1 | import re |
由于DES属于OpenSSL的加密算法,故也可使用OpenSSL的库,C++实现如下:
1 |
|
AES
AES(Advanced Encryption Standard)是新一代的加密标准,其分组长度为128位,密钥长度常为128位。AES的SPN(Substitution-Permutation Network,代换-置换网络) 结构是其加密过程的核心设计思想。SPN 是一种对称密钥分组密码结构,通过多轮重复的 代换(Substitution) 和 置换(Permutation) 操作,结合密钥扩展机制,实现高效的混淆(Confusion)和扩散(Diffusion),从而确保安全性。
AES加密算法的SPN结构有四步操作:逐字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。
逐字节替代SubBytes:
AES 加密中的核心非线性操作步骤,通过S盒对状态矩阵的每个字节进行替换,实现混淆。代码中,SubBytes通过查表高效实现:
1 | // S 盒定义(部分) |
行移位ShiftRows:
行移位(ShiftRows) 是 AES 加密中的关键步骤,属于 置换(Permutation) 操作,负责在状态矩阵的行方向上扩散字节,增强算法的 扩散性(Diffusion),使得单个字节的变化能在多轮迭代后扩散到整个密文分组。其代码实现为:
1 | int shiftRows(uint8_t (*state)[4]) { |
列混淆MixColumns:
是 AES 加密中的核心线性变换步骤,属于扩散(Diffusion)操作,负责在状态矩阵的列方向上混合字节,使得单个字节的变化扩散到整个列。其通过矩阵乘法对每一列进行变换,代码实现为:
1 | // 有限域乘法函数 |
轮密钥异或AddRoundKey:
是 AES 加密和解密中的关键步骤,在每轮中通过 异或(XOR)操作 将当前状态矩阵与轮密钥(Round Key)结合,确保密钥信息融入每一轮的处理过程。它是 AES 中唯一直接使用密钥的步骤,承担了密钥混淆的核心作用。在代码中,轮密钥通常以 32 位字(uint32_t) 存储,需转换为 4×4 字节矩阵后再异或:
1 | int addRoundKey(uint8_t (*state)[4], const uint32_t *roundKey) { |
而AES的密钥生成过程则是将初始密钥(128/192/256位)扩展为多轮加密所需的轮密钥(Round Keys) 的过程。以 AES-128(128位密钥,10轮加密)为例,密钥扩展生成11个轮密钥(每轮使用一个)。
1 | // 密钥扩展函数 |
完整的C语言代码实现可表示为
1 |
|
python代码实现可表示为:
1 | class AES: |
若要使用Python的第三方库,可简化为:
1 | from Crypto.Cipher import AES |
这样使用要先安装对应的库
1 | pip uninstall crypto |
SM4
SM4是中国自主研发的分组密码算法,由国家密码管理局于2006年发布,2012年成为国家标准(GB/T 32907-2016),其分组长度为128位,密钥长度为128位,加密算法为32轮Feistel结构,解密算法为32轮Feistel结构,加密和解密使用相同的轮函数。
秘钥扩展
其分为以下几个步骤:
- 主密钥分割:将128位主密钥分成4个32位字 MK0, MK1, MK2, MK3
- 初始异或:与固定参数 FK[0..3] 异或,得到 K0..K3
- 轮密钥生成:过32轮迭代生成轮密钥 rk[0..31],每轮使用 CK[i] 和变换 T’
对应代码实现如下:
1 |
|
- SM4的加密过程SM4加密采用32轮非平衡Feistel结构,每轮使用一个轮密钥
- 明文分组:将128位明文分为4个32位字 X0, X1, X2, X3
- 32轮迭代:每轮计算 X[i+4] = X[i] ^ T(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i])
- 反序输出:最终结果反序组合为密文 X35, X34, X33, X32
代码实现如下
1 | // 加密中的T变换 |
完整解密过程如下所示:
1 |
|
Python实现:
1 | from gmssl import sm4 |
这种方法需要导入gmssl库
1 | pip install gmssl |