加密算法魔法数字速查

魔法数字(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

初始哈希值(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

搜索建议

搜索 0xC3D2E1F00x5A827999 可快速定位 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]

搜索建议

搜索 0x00000000000080820x800000000000808A,这两个是 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

最有特征的是 0x1B0x36,这是 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 合并表的特征)
  • 搜索 AESaesCryptoJS 关键字

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,或搜索 BigIntegerJSEncryptsetPublicKey


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

搜索建议

搜索 0xEDB883200x77073096(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, 1715, 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 的唯一识别特征。也可搜索 0x79CC45190x7A879D8A


国密 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

搜索建议

搜索 FFFFFFFEFFFFFFFF32C4AE2C(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 0x674523011732584193 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 65537BigInteger JSEncryptsetPublicKey
HMAC 0x36 / 0x5C + 底层哈希常量 ipadopad
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 k0x61707865
RC4 for i 0..255 S[i]=i 模式


最佳实践

同时搜索十进制和十六进制形式:混淆工具有时将常量从十六进制转为十进制(0x674523011732584193),两种形式都要搜索,避免漏找。

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 数据传入传出。


参见

概念基础
加密算法识别
MD5
SHA
代码片段大全

阅读更多

Web 安全基础

1. HTML 转义(服务端渲染必须): 2. CSP(Content Security Policy): 3. HttpOnly Cookie:防止 JS 读取会话 Cookie: 4. 前端框架防护: 攻击者在第三方网站构造一个表单,诱导已登录用户提交,浏览器会自动携带目标站的 Cookie。 触发条件: 1. 用户已登录目标网站(Cookie 有效) 2. 目标 API 仅凭 Cookie 识别用户身份 3. 请求来源未验证 1. CSRF Token(推荐): 2. SameSite Cookie: 3. 验证 Origin/Referer 头:

By yellowdog

HTTP 协议深度指南

HTTP(HyperText Transfer Protocol)是 Web 的基础传输协议,基于 TCP/IP,采用请求/响应模型。 相关文档:Web安全基础(/web-an-quan-ji-chu/) FastAPI完全指南(/fastapi-wan-quan-zhi-nan/) Nginx完全指南(/nginx-wan-quan-zhi-nan/) 幂等性:多次执行相同请求,服务器状态结果相同。PUT /users/1 多次执行结果一致;POST /users 每次创建新资源,非幂等。 浏览器直接从本地缓存读取,不向服务器发送请求。 缓存命中时,状

By yellowdog

系统设计基础

SLA 对照表: 选择建议:无状态服务(Web 层、API 层)优先水平扩展;数据库初期垂直扩展,达到瓶颈后考虑分库分表或读写分离。 缓存穿透(查询不存在的 key,每次都打到 DB): 缓存击穿(热点 key 过期,瞬间大量请求打到 DB): 缓存雪崩(大量 key 同时过期,或缓存服务宕机): 令牌桶 Python 实现: Redis 实现分布式限流(滑动窗口): URL 命名规则: Cursor 分页响应格式: 雪花算法结构(64 bit): 定义:分布式系统不能同时满足以下三个特性: 在分布式环境中 P 是必须保证的,所以实际是 CP vs AP

By yellowdog

算法思路与模板

二分查找要求序列有序,每次将搜索范围缩减一半,时间复杂度 O(log n)。 两个指针从两端向中间收缩,常用于有序数组。 滑动窗口维护一个满足条件的区间 left, right,right 不断向右扩张,条件不满足时收缩 left。 滑动窗口通用框架: 1. 确定"子问题":原问题可以分解为哪些规模更小的同类问题 2. 定义 dpi 或 dpij 的含义,要足够清晰 3. 推导状态转移方程 4. 确定初始状态(边界条件) 5. 确定计算顺序(确保依赖的子问题先计算) 每件物品最多选一次。dpj = 容量为 j 时的最大价值,逆序遍历容量防止重复选取。 每

By yellowdog