加密算法魔法数字速查
魔法数字(Magic Numbers)是加密算法中硬编码的特征常量:初始哈希值、轮常量、S-Box、椭圆曲线参数等。在逆向混淆代码时,全局搜索这些常量是定位加密函数最快的方式。 四个 32-bit 寄存器的初始值,最高频的 MD5 特征: 十进制形式(代码中有时写十进制): MD5 每轮使用 64 个常量 Ti = floor(abs(sin(i+1)) 2^32),前几个最有特征: 优先搜索 0x67452301 或十进制 1732584193,这是 MD5 最独特的特征。 前四个和 MD5 相同,第五个是区别: 十进制:1518500249, 18
官方文档:https://csrc.nist.gov/publications/fips
适用场景:通过特征常量在混淆 JS 代码中快速定位加密算法实现
魔法数字(Magic Numbers)是加密算法中硬编码的特征常量:初始哈希值、轮常量、S-Box、椭圆曲线参数等。在逆向混淆代码时,全局搜索这些常量是定位加密函数最快的方式。
搜索方法:Chrome DevTools → Sources →
Ctrl+Shift+F全局搜索,粘贴下方常量的十六进制或十进制形式。
目录
- MD5
- SHA-1
- SHA-2(SHA-224 / SHA-256 / SHA-384 / SHA-512)
- SHA-3 / Keccak
- AES
- DES / 3DES
- RSA / 大数运算
- HMAC
- Base64
- CRC
- 国密 SM3
- 国密 SM4
- 国密 SM2
- 其他特征
- 搜索技巧速查表
MD5
初始哈希值(IV)
四个 32-bit 寄存器的初始值,最高频的 MD5 特征:
A = 0x67452301
B = 0xEFCDAB89
C = 0x98BADCFE
D = 0x10325476
十进制形式(代码中有时写十进制):
1732584193 ← 0x67452301
-271733879 ← 0xEFCDAB89(有符号 32-bit)
-1732584194 ← 0x98BADCFE
271733878 ← 0x10325476
T 表常量(轮常量,来自 sin 函数)
MD5 每轮使用 64 个常量 T[i] = floor(abs(sin(i+1)) * 2^32),前几个最有特征:
T[1] = 0xD76AA478 (3614090360)
T[2] = 0xE8C7B756 (3905402710)
T[3] = 0x242070DB (606105819)
T[4] = 0xC1BDCEEE
T[5] = 0xF57C0FAF
T[6] = 0x4787C62A
T[7] = 0xA8304613
T[8] = 0xFD469501
T[9] = 0x698098D8
T[10] = 0x8B44F7AF
T[11] = 0xFFFF5BB1
T[12] = 0x895CD7BE
T[13] = 0x6B901122
T[14] = 0xFD987193
T[15] = 0xA679438E
T[16] = 0x49B40821
搜索建议
优先搜索 0x67452301 或十进制 1732584193,这是 MD5 最独特的特征。
SHA-1
初始哈希值(IV)
前四个和 MD5 相同,第五个是区别:
H0 = 0x67452301
H1 = 0xEFCDAB89
H2 = 0x98BADCFE
H3 = 0x10325476
H4 = 0xC3D2E1F0 ← SHA-1 独有,最佳搜索目标
四个轮常量(K 值)
K0 = 0x5A827999 (轮 1-20,来自 sqrt(2)/4)
K1 = 0x6ED9EBA1 (轮 21-40,来自 sqrt(3)/4)
K2 = 0x8F1BBCDC (轮 41-60,来自 sqrt(5)/4)
K3 = 0xCA62C1D6 (轮 61-80,来自 sqrt(10)/4)
十进制:1518500249, 1859775393, 2400959708, 3395469782
搜索建议
搜索 0xC3D2E1F0 或 0x5A827999 可快速定位 SHA-1。
SHA-2
SHA-256 初始哈希值(H0–H7)
来自前 8 个素数平方根的小数部分:
H0 = 0x6A09E667
H1 = 0xBB67AE85
H2 = 0x3C6EF372
H3 = 0xA54FF53A
H4 = 0x510E527F
H5 = 0x9B05688C
H6 = 0x1F83D9AB
H7 = 0x5BE0CD19
SHA-256 轮常量(K,64 个)
来自前 64 个素数立方根的小数部分,前 16 个:
K[0] = 0x428A2F98
K[1] = 0x71374491
K[2] = 0xB5C0FBCF
K[3] = 0xE9B5DBA5
K[4] = 0x3956C25B
K[5] = 0x59F111F1
K[6] = 0x923F82A4
K[7] = 0xAB1C5ED5
K[8] = 0xD807AA98
K[9] = 0x12835B01
K[10] = 0x243185BE
K[11] = 0x550C7DC3
K[12] = 0x72BE5D74
K[13] = 0x80DEB1FE
K[14] = 0x9BDC06A7
K[15] = 0xC19BF174
K[16] = 0xE49B69C1
K[17] = 0xEFBE4786
K[18] = 0x0FC19DC6
K[19] = 0x240CA1CC
K[20] = 0x2DE92C6F
K[21] = 0x4A7484AA
K[22] = 0x5CB0A9DC
K[23] = 0x76F988DA
K[24] = 0x983E5152
K[25] = 0xA831C66D
K[26] = 0xB00327C8
K[27] = 0xBF597FC7
K[28] = 0xC6E00BF3
K[29] = 0xD5A79147
K[30] = 0x06CA6351
K[31] = 0x14292967
K[32] = 0x27B70A85
K[33] = 0x2E1B2138
K[34] = 0x4D2C6DFC
K[35] = 0x53380D13
K[36] = 0x650A7354
K[37] = 0x766A0ABB
K[38] = 0x81C2C92E
K[39] = 0x92722C85
K[40] = 0xA2BFE8A1
K[41] = 0xA81A664B
K[42] = 0xC24B8B70
K[43] = 0xC76C51A3
K[44] = 0xD192E819
K[45] = 0xD6990624
K[46] = 0xF40E3585
K[47] = 0x106AA070
K[48] = 0x19A4C116
K[49] = 0x1E376C08
K[50] = 0x2748774C
K[51] = 0x34B0BCB5
K[52] = 0x391C0CB3
K[53] = 0x4ED8AA4A
K[54] = 0x5B9CCA4F
K[55] = 0x682E6FF3
K[56] = 0x748F82EE
K[57] = 0x78A5636F
K[58] = 0x84C87814
K[59] = 0x8CC70208
K[60] = 0x90BEFFFA
K[61] = 0xA4506CEB
K[62] = 0xBEF9A3F7
K[63] = 0xC67178F2
SHA-224 初始哈希值
SHA-224 是 SHA-256 截断版,但用不同 IV:
H0 = 0xC1059ED8
H1 = 0x367CD507
H2 = 0x3070DD17
H3 = 0xF70E5939
H4 = 0xFFC00B31
H5 = 0x68581511
H6 = 0x64F98FA7
H7 = 0xBEFA4FA4
SHA-512 初始哈希值(H0–H7,64-bit)
H0 = 0x6A09E667F3BCC908
H1 = 0xBB67AE8584CAA73B
H2 = 0x3C6EF372FE94F82B
H3 = 0xA54FF53A5F1D36F1
H4 = 0x510E527FADE682D1
H5 = 0x9B05688C2B3E6C1F
H6 = 0x1F83D9ABFB41BD6B
H7 = 0x5BE0CD19137E2179
SHA-384 初始哈希值
H0 = 0xCBBB9D5DC1059ED8
H1 = 0x629A292A367CD507
H2 = 0x9159015A3070DD17
H3 = 0x152FECD8F70E5939
H4 = 0x67332667FFC00B31
H5 = 0x8EB44A8768581511
H6 = 0xDB0C2E0D64F98FA7
H7 = 0x47B5481DBEFA4FA4
搜索建议
0x6A09E667 是 SHA-256 最有特征的常量。SHA-512 搜索 0x6A09E667F3BCC908(64-bit)。
SHA-3 / Keccak
轮常量 RC(24 轮,64-bit)
RC[0] = 0x0000000000000001
RC[1] = 0x0000000000008082
RC[2] = 0x800000000000808A
RC[3] = 0x8000000080008000
RC[4] = 0x000000000000808B
RC[5] = 0x0000000080000001
RC[6] = 0x8000000080008081
RC[7] = 0x8000000000008009
RC[8] = 0x000000000000008A
RC[9] = 0x0000000000000088
RC[10] = 0x0000000080008009
RC[11] = 0x000000008000000A
RC[12] = 0x000000008000808B
RC[13] = 0x800000000000008B
RC[14] = 0x8000000000008089
RC[15] = 0x8000000000008003
RC[16] = 0x8000000000008002
RC[17] = 0x8000000000000080
RC[18] = 0x000000000000800A
RC[19] = 0x800000008000000A
RC[20] = 0x8000000080008081
RC[21] = 0x8000000000008080
RC[22] = 0x0000000080000001
RC[23] = 0x8000000080008008
Rho 偏移量
[1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44]
搜索建议
搜索 0x0000000000008082 或 0x800000000000808A,这两个是 Keccak 最有辨识度的 64-bit 常量。
AES
S-Box(正向,256 字节)
S-Box 前 16 字节(第一行):
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76
完整 S-Box(16×16,十六进制):
63 7c 77 7b f2 6b 6f c5 30 01 67 2b fe d7 ab 76
ca 82 c9 7d fa 59 47 f0 ad d4 a2 af 9c a4 72 c0
b7 fd 93 26 36 3f f7 cc 34 a5 e5 f1 71 d8 31 15
04 c7 23 c3 18 96 05 9a 07 12 80 e2 eb 27 b2 75
09 83 2c 1a 1b 6e 5a a0 52 3b d6 b3 29 e3 2f 84
53 d1 00 ed 20 fc b1 5b 6a cb be 39 4a 4c 58 cf
d0 ef aa fb 43 4d 33 85 45 f9 02 7f 50 3c 9f a8
51 a3 40 8f 92 9d 38 f5 bc b6 da 21 10 ff f3 d2
cd 0c 13 ec 5f 97 44 17 c4 a7 7e 3d 64 5d 19 73
60 81 4f dc 22 2a 90 88 46 ee b8 14 de 5e 0b db
e0 32 3a 0a 49 06 24 5c c2 d3 ac 62 91 95 e4 79
e7 c8 37 6d 8d d5 4e a9 6c 56 f4 ea 65 7a ae 08
ba 78 25 2e 1c a6 b4 c6 e8 dd 74 1f 4b bd 8b 8a
70 3e b5 66 48 03 f6 0e 61 35 57 b9 86 c1 1d 9e
e1 f8 98 11 69 d9 8e 94 9b 1e 87 e9 ce 55 28 df
8c a1 89 0d bf e6 42 68 41 99 2d 0f b0 54 bb 16
逆向 S-Box(解密用)
第一行:
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB
Rcon(轮密钥扩展常量,10 个)
Rcon[1] = 0x01
Rcon[2] = 0x02
Rcon[3] = 0x04
Rcon[4] = 0x08
Rcon[5] = 0x10
Rcon[6] = 0x20
Rcon[7] = 0x40
Rcon[8] = 0x80
Rcon[9] = 0x1B
Rcon[10] = 0x36
最有特征的是 0x1B 和 0x36,这是 GF(2^8) 模 0x11B 运算的结果。
MixColumns 使用的 GF(2^8) 乘法表
xtime(乘以 2)的模多项式:0x11B(即 x^8 + x^4 + x^3 + x + 1)
MixColumns 矩阵:
[2, 3, 1, 1]
[1, 2, 3, 1]
[1, 1, 2, 3]
[3, 1, 1, 2]
预计算的 mul2 表前 16 字节:
0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E
搜索建议
- 搜索 S-Box 前几字节:
0x63,0x7c,0x77,0x7b或字符串"637c777b" - 搜索
0x1b636363(SubBytes + ShiftRows 合并表的特征) - 搜索
AES、aes、CryptoJS关键字
DES / 3DES
IP 置换表(初始置换,64 个元素)
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
IP⁻¹ 逆置换表
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
S-Box(8 个,每个 4×16,值 0-15)
S1 盒(最常被搜索,用于快速识别):
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
S2 盒:
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
PC-1 置换(56 位密钥选择)
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
搜索建议
DES S-Box 中的 14, 4, 13, 1, 2, 15, 11, 8 序列极为特征,或搜索 IP 表中的 58, 50, 42, 34。
RSA / 大数运算
RSA 本身没有固定的魔法数字(密钥是随机生成的),但可以通过以下特征识别:
DER/ASN.1 编码特征字节
| 标识 | 含义 |
|---|---|
0x30 0x82 |
SEQUENCE,后跟 2 字节长度(私钥或证书常见开头) |
0x02 0x01 0x00 |
INTEGER 0(版本号,私钥 PKCS#1 开头) |
0x30 0x0D 0x06 0x09 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x01 0x0B |
RSA-SHA256 OID |
PEM 文件头特征
-----BEGIN RSA PRIVATE KEY----- ← PKCS#1 私钥
-----BEGIN PRIVATE KEY----- ← PKCS#8 私钥
-----BEGIN PUBLIC KEY----- ← 公钥
-----BEGIN CERTIFICATE-----
大数运算库特征
- jsbn 库:字符串
"BigInteger","Montgomery",bnpFromString - forge 库:字符串
"forge","pki","privateKeyFromPem" - JSEncrypt 库:字符串
"JSEncrypt","setPublicKey","encrypt"
常用公钥指数
e = 0x10001 = 65537 ← 绝大多数 RSA 公钥的 e 值,直接搜索 65537
e = 3 ← 旧版/弱密钥
e = 17
搜索建议
搜索 65537(十进制)或 0x10001,或搜索 BigInteger、JSEncrypt、setPublicKey。
HMAC
HMAC 本身没有独立的魔法数字,它是对底层哈希算法的包装,特征常量同底层算法(MD5/SHA)。
HMAC 的两个 pad 常量:
ipad = 0x36 (重复 blockSize 次,内部填充)
opad = 0x5C (重复 blockSize 次,外部填充)
代码中常见写法:
// 搜索这两个十六进制常量
0x36363636... ← ipad 填充后的结果(64 个 0x36)
0x5c5c5c5c... ← opad 填充后的结果(64 个 0x5c)
Base64
标准字母表
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
URL 安全变体
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
搜索建议
直接搜索字符串 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno"(前 47 字符),这段字母表在大多数实现中会以字符串字面量出现。
自定义 Base64 字母表也以相同格式出现,只是字符不同,需要人工识别。
CRC
CRC-32 多项式
正向多项式: 0x04C11DB7
反向多项式: 0xEDB88320 ← 最常见,搜索这个
CRC-32 查找表(前 8 个)
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3
CRC-16/CCITT 多项式
0x1021 ← CRC-16/CCITT
0x8005 ← CRC-16/IBM
搜索建议
搜索 0xEDB88320 或 0x77073096(CRC-32 表第二项)。
国密 SM3
SM3 是中国国密哈希标准,输出 256 位,结构类似 SHA-256 但完全不同。
初始哈希值(IV,8 个 32-bit)
V0 = 0x7380166F
V1 = 0x4914B2B9
V2 = 0x172442D7
V3 = 0xDA8A0600
V4 = 0xA96F30BC
V5 = 0x163138AA
V6 = 0xE38DEE4D
V7 = 0xB0FB0E4E
0x7380166F 是 SM3 最核心的特征常量,全网唯一。
T 常量(轮常量,两个)
T_j = 0x79CC4519 (j = 0..15,前 16 轮)
T_j = 0x7A879D8A (j = 16..63,后 48 轮)
代码中常见形式:
// 两个常量循环左移
0x79CC4519
0x7A879D8A
P0 / P1 置换函数特征
P0(X) = X ^ ROL(X, 9) ^ ROL(X, 17) // 用于消息扩展
P1(X) = X ^ ROL(X, 15) ^ ROL(X, 23) // 用于压缩函数
代码中会出现位移量 9, 17 或 15, 23 配对。
W 消息扩展特征
// W[j] = P1(W[j-16] ^ W[j-9] ^ ROL(W[j-3], 15)) ^ ROL(W[j-13], 7) ^ W[j-6]
// 关键常数索引: 16, 9, 3, 13, 6
搜索建议
搜索 0x7380166F 即可,这是 SM3 的唯一识别特征。也可搜索 0x79CC4519 或 0x7A879D8A。
国密 SM4
SM4 是中国国密分组密码标准,128-bit 块,128-bit 密钥,32 轮,类似 AES。
FK 常量(密钥扩展初始值)
FK[0] = 0xA3B1BAC6
FK[1] = 0x56AA3350
FK[2] = 0x677D9197
FK[3] = 0xB27022DC
0xA3B1BAC6 是 SM4 最核心的特征常量。
CK 常量(轮密钥生成,32 个)
CK[0] = 0x00070E15
CK[1] = 0x1C232A31
CK[2] = 0x383F464D
CK[3] = 0x545B6269
CK[4] = 0x70777E85
CK[5] = 0x8C939AA1
CK[6] = 0xA8AFB6BD
CK[7] = 0xC4CBD2D9
CK[8] = 0xE0E7EEF5
CK[9] = 0xFC030A11
CK[10] = 0x181F262D
CK[11] = 0x343B4249
CK[12] = 0x50575E65
CK[13] = 0x6C737A81
CK[14] = 0x888F969D
CK[15] = 0xA4ABB2B9
CK[16] = 0xC0C7CED5
CK[17] = 0xDCE3EAF1
CK[18] = 0xF8FF060D
CK[19] = 0x141B2229
CK[20] = 0x30373E45
CK[21] = 0x4C535A61
CK[22] = 0x686F767D
CK[23] = 0x848B9299
CK[24] = 0xA0A7AEB5
CK[25] = 0xBCC3CAD1
CK[26] = 0xD8DFE6ED
CK[27] = 0xF4FB0209
CK[28] = 0x10171E25
CK[29] = 0x2C333A41
CK[30] = 0x484F565D
CK[31] = 0x646B7279
S-Box(256 字节)
前 16 字节:
0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7,
0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05
完整 S-Box(16×16):
D6 90 E9 FE CC E1 3D B7 16 B6 14 C2 28 FB 2C 05
2B 67 9A 76 2A BE 04 C3 AA 44 13 26 49 86 06 99
9C 42 50 F4 91 EF 98 7A 33 54 0B 43 ED CF AC 62
E4 B3 1C A9 C9 08 E8 95 80 DF 94 FA 75 8F 3F A6
47 07 A7 FC F3 73 17 BA 83 59 3C 19 E6 85 4F A8
68 6B 81 B2 71 64 DA 8B F8 EB 0F 4B 70 56 9D 35
1E 24 0E 5E 63 58 D1 A2 25 22 7C 3B 01 21 78 87
D4 00 46 57 9F D3 27 52 4C 36 02 E7 A0 C4 C8 9E
EA BF 8A D2 40 C7 38 B5 A3 F7 F2 CE F9 61 15 A1
E0 AE 5D A4 9B 34 1A 55 AD 93 32 30 F5 8C B1 E3
1D F6 E2 2E 82 66 CA 60 C0 29 23 AB 0D 53 4E 6F
D5 DB 37 45 DE FD 8E 2F 03 FF 6A 72 6D 6C 5B 51
8D 1B AF 92 BB DD BC 7F 11 D9 5C 41 1F 10 5A D8
0A C1 31 88 A5 CD 7B BD 2D 74 D0 12 B8 E5 B4 B0
89 69 97 4A 0C 96 77 7E 65 B9 F1 09 C5 6E C6 84
18 F0 7D EC 3A DC 4D 20 79 EE 5F 3E D7 CB 39 48
L / L' 线性变换特征
L(B) = B ^ ROL(B,2) ^ ROL(B,10) ^ ROL(B,18) ^ ROL(B,24) // 数据加密用
L'(B) = B ^ ROL(B,13) ^ ROL(B,23) // 密钥扩展用
代码中会出现位移量 2, 10, 18, 24 组合,或 13, 23 组合。
搜索建议
搜索 0xA3B1BAC6(FK[0])或 0x00070E15(CK[0])是最快的识别方式。
国密 SM2
SM2 是中国国密非对称算法(椭圆曲线),256 位,对应 ECDSA + ECIES。
推荐曲线参数(SM2 标准曲线)
素数域 p(模数):
p = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
曲线系数 a:
a = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC
曲线系数 b:
b = 0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93
基点 G 的 x 坐标(Gx):
Gx = 0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7
基点 G 的 y 坐标(Gy):
Gy = 0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0
群的阶 n:
n = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
余因子 h:
h = 0x01
SM2 ZA 值计算中的 ID 字段
默认用户 ID(国密标准规定):
"1234567812345678" (ASCII: 0x31323334353637383132333435363738)
十六进制长度前缀:
0x0080 ← ID 的 bit 长度(16字节 × 8 = 128 bit)
SM2 签名特征
SM2 签名结构(r, s 各 32 字节),常以 DER 编码:
0x30 [len] 0x02 [r_len] [r] 0x02 [s_len] [s]
或以拼接形式:64 字节 = 32 字节 r + 32 字节 s
搜索建议
搜索 FFFFFFFEFFFFFFFF 或 32C4AE2C(Gx 前缀),国密 SM2 相关代码中这两个字符串必然出现。也可搜索 "1234567812345678"(默认 ID)。
其他特征
RC4 / ARCFOUR
RC4 没有固定的魔法数字,但初始化阶段会对 S 盒进行 i = 0..255 的初始化,特征是 256 字节的顺序数组:
// 搜索这种初始化模式
for (var i = 0; i < 256; i++) S[i] = i;
Rabbit 流密码
// a 常量
A0 = 0x4D34D34D, A1 = 0xD34D34D3, A2 = 0x34D34D34,
A3 = 0x4D34D34D, A4 = 0xD34D34D3, A5 = 0x34D34D34,
A6 = 0x4D34D34D, A7 = 0xD34D34D3
ChaCha20 / Salsa20
常量字符串(ASCII):
"expa" "nd 3" "2-by" "te k"
// 拼接:expand 32-byte k
// 十六进制:0x65787061 0x6E642033 0x322D6279 0x7465206B
16 字节密钥版本:expand 16-byte k
搜索建议:搜索字符串 "expand 32-byte k" 或 0x61707865("expa" 的小端序)。
PBKDF2 / bcrypt / scrypt
这些密钥派生函数本身无特征常量,但通常配合 SHA 使用,可通过字符串 "PBKDF2", "bcrypt", "scrypt" 定位。
搜索技巧速查表
| 算法 | 首选搜索目标 | 备选 |
|---|---|---|
| MD5 | 0x67452301 或 1732584193 |
0xD76AA478 |
| SHA-1 | 0xC3D2E1F0 |
0x5A827999 |
| SHA-256 | 0x6A09E667 |
0x428A2F98 |
| SHA-512 | 0x6A09E667F3BCC908(64-bit) |
0xBB67AE8584CAA73B |
| SHA-3/Keccak | 0x0000000000008082 |
0x800000000000808A |
| AES | 0x63,0x7c,0x77,0x7b(S-Box)或 637c777b |
0x1B(Rcon) |
| DES | 14,4,13,1,2,15,11,8(S1盒首行) |
58,50,42,34(IP表) |
| RSA | 65537 或 BigInteger |
JSEncrypt、setPublicKey |
| HMAC | 0x36 / 0x5C + 底层哈希常量 |
ipad、opad |
| Base64 | ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno |
— |
| CRC-32 | 0xEDB88320 |
0x77073096 |
| SM3 | 0x7380166F |
0x79CC4519 |
| SM4 | 0xA3B1BAC6(FK[0]) |
0x00070E15(CK[0]) |
| SM2 | FFFFFFFEFFFFFFFF(p 前缀) |
32C4AE2C(Gx 前缀) |
| ChaCha20 | expand 32-byte k 或 0x61707865 |
— |
| RC4 | for i 0..255 S[i]=i 模式 |
— |
最佳实践
同时搜索十进制和十六进制形式:混淆工具有时将常量从十六进制转为十进制(0x67452301 → 1732584193),两种形式都要搜索,避免漏找。
S-Box 搜索只需前几个字节:AES S-Box 共 256 字节,搜索前 8 个字节(0x63, 0x7c, 0x77, 0x7b)即可定位,无需完整匹配;DES S-Box 是 8 组 4×16 的表格,搜索第一组开头的 14, 4, 13, 1 足够。
确认常量归属时看上下文函数结构:0x67452301 在 MD5 和 SHA-1 中都出现,确认用途需看后续赋值是否有 0x5a827999(SHA-1 轮常量)还是 0xd76aa478(MD5 第一轮常量)。
国密算法优先搜索 0xd8823b6f(SM3)或 0x7979e729(SM4 S-Box 首值):国密算法的 WebAssembly 实现中常量仍以数值形式出现,与纯 JS 实现搜索方式相同。
找到函数后打断点确认输入输出:定位到疑似加密函数后,在函数入口打断点,触发请求后查看参数值,确认是目标加密逻辑再进一步分析,避免在无关函数上浪费时间。
常见陷阱
陷阱:同一常量在多个算法中出现导致误判
现象: 搜索 0x67452301 找到函数,按 MD5 还原后结果不对。
原因: SHA-1 使用同一组初始哈希向量,两者在这 4 个常量上完全相同。
解决: 继续搜索 MD5 独有的轮常量(0xd76aa478 是 MD5 第一轮,0x5a827999 是 SHA-1 第一轮),根据后续常量区分。
陷阱:Webpack 打包后常量被 terser 折叠
现象: 搜索特征常量找不到任何结果。
原因: terser 等压缩工具会把多个使用同一常量的地方内联展开,或把常量存入数组索引后通过偏移引用,导致原始常量字面量不存在。
解决: 在 Network 请求断点处单步追踪调用栈,找到负责生成签名的函数后下函数断点,不依赖全文搜索。
陷阱:WASM 实现中搜索不到 JS 层常量
现象: 全局搜索所有魔法数字均无结果,但请求中存在加密签名。
原因: 加密逻辑在 WebAssembly 中实现,JS 只负责调用 wasm 模块;常量在编译后的二进制中,文本搜索无效。
解决: 搜索 WebAssembly.instantiate、.wasm 请求,下载 WASM 文件用 wasm2wat 反汇编为文本后再搜索常量;或直接在 JS-WASM 交互层 Hook 数据传入传出。