逆向中常见的加密算法
base 系列
base64 编码过程
如上图所示:
- 将字符串转换成二进制序列
- 按每 6 个二进制位为一组,分成若干组
- 如果不足 6 位,则最低位补 0
- 每 6 位组成一个新的字节,高位补 00,构成一个新的二进制序列
- 根据 base64 索引表中的值找到对应的字符
- 凑齐 4 字节整数倍,在末尾补 “=” 号
特征识别
- 编码表
- 密文长度 %4==0,字符特征
- 加密填充符
- bit:3 * 8 变 4 * 6
常规魔改
- 编码表(TLS、SMC 等各种反调试位置)
变表 base64 解密示例:
1 | import base64 |
RC4
一个类似于逐字节异或的加密算法
它属于对称加密算法中的流密码加密算法,流密码不对明文数据进行分组,而是用密钥生成与明文一样长短的密码流对明文进行加密
特征识别
- 初始化和加密分离
- sbox 初始化 s[i]=i,密钥填充
- 取模运算,对明文处理只有最后一部分
加密过程
1 | void rc4_init(unsigned char* s, unsigned char* key, int len){ |
常规魔改
- 异或的时候加入其它算数运算
- 取模长度更改
Tea 系列
特征识别
- 常量特征:delta 0x9e3779b9
- 密钥特征:4个32位字符
- 明文输入:32位字符为单位
- 异或&移位特征
tea 加密过程
1 | void encrypt(uint32_t* v, uint32_t* k) { |
tea 解密过程
1 |
|
xtea 加密过程
1 | void encrypt(uint32_t* v, uint32_t* k) { |
xxtea 加密过程
1 | v = 明文 |
xxtea 解密过程
1 | from ctypes import c_uint32 |
AES
特征识别
- sbox 16*16 常量特征
1 | unsigned char S[256] = { |
- 加密过程:密钥扩展–>轮密钥生成–>字节替换、行移位–>列替换和轮密钥加
- 密钥长度和轮数的对应
- 128bits–>10rounds
- 192bits–>12rounds
- 256bits–>14rounds
AES 解密过程
1 | from Crypto.Cipher import AES |
DES
Blowfish
特征识别
- 常量特征:16 进制的 pai hex 数据填充 PBOX
1 | p[0] = 0x243F6A88 |
- 对称加密
- 密钥长度不定–>32-448位
国密 SM4
特征识别
- 分组长度、密钥长度为 128bit
- 32 轮运算 + 反序变换
- sbox 常量特征
1 | SBOX = [ |
- 密钥扩展左移 13、23 位,常量
1 | FK = {0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc}; |
- 加密过程线性变换左移 2、10、18、24 位
Hash
hash 不可逆,所以如果解题遇到 hash 基本以算法识别+撞库为主
md5、sha1、sha256、sha384、sha512 等等
加密过程有大量移位操作且不可逆
特征识别
- MD5 常量特征
1 | ABCD |
- MD5 64轮移位表
CRC64
CRC 校验的本质就是多项式除法
CRC64 解密脚本
1 | import struct |
CRC64 加密函数
1 | def en(buf): |