百趣云 百趣云的博客

SM4 国密算法识别:政务金融 App 的加密标配

为什么会遇到 SM4

逆向政务、银行、国企 App 时,加密算法会从 AES 换成 SM4——国家商用密码标准。合规要求(等保、密评)决定了这些领域的 App 必须用国密算法。遇到"结构像 AES 但常量对不上"的分组加密,就要想到 SM4。

SM4 与 AES 的结构对比

维度SM4AES
分组长度128 位128 位
密钥长度128 位(唯一)128/192/256
轮数32 轮10/12/14 轮
结构非平衡 FeistelSPN
S 盒1 个 8×8 S 盒1 个 8×8 S 盒(不同的表)

识别:SM4 的特征常量

S 盒:SM4 的 S 盒开头是:

d6 90 e9 fe cc e1 3d b5 16 b4 14 c2 28 fb 2c 05

IDA 搜 D6 90 E9 FE CC E1——和 AES 的 63 7C 77 7B 一样,这是 SM4 的指纹。

系统参数 FK(密钥扩展用):

A3B1BAC6 56AA3350 677D9197 B27022DC

固定参数 CK(32 个轮密钥常量):

00070E15 1C232A31 383F464D 545B6269 ...

三组常量搜到任何一组即实锤 SM4。Java 层更简单:搜 SM4 字符串、Sm4Util 类名、或 BouncyCastle 的 SM4Engine

模式与填充:和 AES 相同的概念

SM4 同样有 ECB/CBC/CTR 等模式、PKCS7 等填充,判断方法和 AES 一样(见 AES 识别篇)。政务 App 的常见组合是 SM4-ECB-PKCS7(简单场景)和 SM4-CBC(传输场景)。

Python 实现与对拍

# 用 gmssl 库
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT

key = b'0123456789abcdeffedcba9876543210'  # 16 字节
cipher = CryptSM4()
cipher.set_key(key, SM4_ENCRYPT)

# ECB 模式
ciphertext = cipher.crypt_ecb(plaintext)

# CBC 模式(gmssl 的 crypt_cbc 需要 iv 参数)
cipher.set_key(key, SM4_DECRYPT)
plaintext = cipher.crypt_cbc(iv, ciphertext)

对拍流程和 AES 相同:hook 拿 key/iv → 已知明文加密 → 和 App 输出对比。

精髓一:国密全家桶的联动

政务金融 App rarely 只用 SM4,通常是国密全家桶:

  • SM2:非对称(替代 RSA),用于密钥交换/签名
  • SM3:摘要(替代 SHA-256),用于完整性/签名
  • SM4:对称(替代 AES),用于数据加密

识别到 SM4 后,顺带检查 SM2/SM3 的存在。SM3 的识别常量是 IV 7380166F 4914B2B9 ...,SM2 是椭圆曲线运算(识别曲线参数)。

精髓二:合规场景的密钥管理更规范

政务金融 App 的密钥管理比互联网 App 规范:

  • 密钥很少硬编码(过不了密评)
  • 常见做法是 SM2 加密 SM4 密钥(数字信封):SM2 公钥加密随机的 SM4 密钥传输,SM4 加密业务数据
  • 逆向要点变成:找 SM2 的私钥/公钥体系 + hook SM4 密钥的生成点

hook 点选择:Sm4Util 类的 setKey/init 方法,或 BouncyCastle 的 SM4Engine.init——key 明文必经之地。

总结

  1. 政务金融 App 用国密,SM4 替代 AES
  2. 识别常量:S 盒 D6 90 E9 FE、FK 参数、CK 常量表
  3. 模式填充概念与 AES 相同,gmssl 库直接对拍
  4. 注意 SM2/SM3 联动,数字信封结构下 hook SM4 密钥生成点

交流微信:run1255

By 百趣云 阅读量:73 On