第4章:密码学基础回顾——对称/非对称加密、哈希、数字签名

做密码改造审计,你绕不开密码学。这几类基础算法就像工具箱里的扳手、螺丝刀和扭矩仪——你得知道什么时候用哪个,怎么用,更要知道它们各自的死穴在哪。我在做合规审计时看过太多代码,明明用了AES,密钥却硬编码在源码里;明明上了数字签名,摘要算法却是MD5。嗯,这章咱们就捋一遍基础,把坑都标记出来。

4.1 对称加密:又快又痛

对称加密,说白了就是加密和解密用同一个密钥。像你家大门,锁和钥匙是一对一配好的。优点就一个字——快。大数据量、实时通信、磁盘加解密,基本都是对称算法的活儿。

常见的有AES、SM4。AES支持128/192/256位密钥,我一般推荐AES-256-GCM——带认证加密,密文被篡改能立刻发现。SM4是国标,接口参数跟AES差不多,但算法轮数、S盒设计不一样。

核心指标对照

算法密钥长度分组模式审计要点
AES128/192/256位ECB/CBC/CTR/GCM禁止ECB模式;必须使用随机IV
SM4128位ECB/CBC/CTR/GCM检查是否使用国密规范填充(PKCS7)

避坑指南

我曾经审计过一个互联网支付系统,日志里赫然出现了ECB模式加密的银行账号——相同明文块产生相同密文块,看你一眼就知道你转账了多少钱。ECB一定是安检红线,日志中出现就要标记为高危。

记得检查IV(初始化向量)是否随机生成且每次不同。我在项目中看到有人把IV写死成全零,加密结果成了“伪随机”,密钥猜测难度直接降低。好的习惯:IV必须是加密引擎产生的随机数,且至少12字节(GCM模式)或16字节(CBC模式)。

4.2 非对称加密:慢但安全

非对称加密有两个密钥——公钥和私钥。公钥可以公开,私钥只有自己持有。RSA、ECC、SM2是典型代表。非对称加密速度慢,一般不直接加密大数据,而是用来加密对称密钥(密钥交换)或数字签名。

// 示例:公钥加密对称密钥,对称密钥加密海量日志
byte[] sessionKey = AES.generateKey();
byte[] encryptedKey = RSA.encrypt(sessionKey, rsaPublicKey);
byte[] ciphertext = AES.encrypt(logData, sessionKey);
// 审计日志只需要记录:公钥指纹、加密后的sessionKey、ciphertext

RSA 2048位是目前合规底线, SM2 256位对标RSA 3072。我个人习惯把密钥长度作为合规检查第一项——低于2048位的RSA直接打回。

经验之谈

公钥必须经过证书链验证,不能直接信任代码里硬编码的字符串。我在某云平台的日志里见过直接写死的base64公钥,连证书都没——万一私钥泄露,整个系统的信任链就断了。

4.3 哈希函数:不是加密,是指纹

哈希函数把任意长度的输入变成固定长度的摘要。它不是加密——你不可能从哈希值反推出原文。审计里哈希最常用的场景是完整性校验:存哈希,然后验哈希。

现在MD5 / SHA-1必须禁用。我见过一个遗留系统还在用SHA-1校验日志完整性,被审计老师直接标注为「严重违规」。SHA-256是底线,国密SM3同等强度。

  • SHA-256:输出256位,抗碰撞性满足一般合规要求
  • SM3:输出256位,国密系列,很多政府/金融系统强制要求
  • HMAC:带密钥的哈希,用于消息认证码(MAC)

哈希函数遇到冲突怎么办?概率极低,但不能完全忽略。对于重要日志,建议结合HMAC + 时间戳 + 随机数做防重放。

4.4 数字签名:防抵赖的定海神针

数字签名 = 哈希 + 非对称加密。先对原文哈希,再用私钥加密哈希值。接收方用公钥解密哈希值,再自己算一次原文哈希——两个对上,说明原文没被改过,且签名确实来自私钥持有者。

合规审计里,数字签名是日志防篡改、防抵赖的基石。我审核改造方案时,第一个问题总是:“签名算法是什么?密钥怎么管理的?”

签名算法哈希搭配合规状态审计建议
RSA-PSSSHA-256推荐参数必须指定salt长度
ECDSASHA-256 / SM3推荐曲线必须使用NIST P-256或SM2曲线
SM2SM3国密强制检查签名值与公钥曲线一致性
RSA-PKCS1v1.5SHA-1禁用迁移到RSA-PSS或ECDSA

4.5 知识结构图:四类算法在审计中的位置

密码学基础知识体系(审计视角) 对称加密 非对称加密 哈希函数 数字签名 共同密钥,速度快 密钥对,安全交换 不可逆,完整性校验 哈希+非对称,防抵赖 审计通用关注点:算法强度、密钥管理、随机数质量、合规国密 ⚠ 一定要避开的坑 • 禁止ECB模式 • 密钥不能硬编码 • MD5/SHA-1禁用 • 随机数必须真随机

4.6 实战中的组合拳

密码改造不是单一算法的事。一套日志合规记录方案,通常这样配:

  1. 用AES-256-GCM加密日志原始内容
  2. 用SM2签名(如果客户要求国密)或ECDSA签名
  3. 对关键字段(时间、MAC地址、用户ID)用SM3或SHA-256计算哈希,作为防篡改指纹
  4. 整个日志链路的随机数(IV、nonce、盐值)全部使用硬件真随机数发生器生成

为什么要这么做?我遇到过一家公司,日志加密用了AES-256-CBC,签名却用了RSA-1024-PKCS1v1.5(SHA-1)。这就好比你给金库装了最厚的门,结果钥匙是纸糊的——攻击者只要哈希碰撞就能伪造签名。安全强度永远取决于最弱的一环。

4.7 审计日志里这些字段必须记录

字段说明示例值
cipher_algorithm加密算法全称AES-256-GCM
key_id密钥标识(非明文)key-v1-2024-001
signature_algorithm签名算法ECDSA-P256SHA256
hash_algorithm摘要算法SHA-256
random_source随机数来源hw-rng / kernel-random
iv_nonceIV或Nonce值(base64)A8v3k...
session_key_enc加密后的会话密钥(base64长串)

我个人习惯在记录里同时保存算法参数——比如AES的填充模式、GCM的tag长度、ECDSA的曲线名称。这些信息在事后验证时能救命,不会出现“我记得当时用的GCM,但审计人员查出来你日志里只写了AES”这种尴尬。

小技巧

检查日志里是否记录了「算法版本」。我曾经审计时发现同一系统不同模块用了不同AES密钥长度——日志里只写了AES,没写128还是256。后来加了个版本字段,以后一看就明白,合规检查也省力。

4.8 完整性保护链条

为什么哈希和数字签名要配合?单用哈希,攻击者可以同时篡改原文和哈希值。单用数字签名,没有哈希做摘要,签名数据量太大。所以日志记录链条一般是:

  • 原文 → SHA-256摘要 → 对摘要做SM2签名 → 存(原文 + 签名值 + 算法信息)
  • 校验时:重新计算摘要 → 用公钥验证签名 → 比对

嗯,绕了这几步,就是要确保日志不可否认、不可篡改。密码改造审计中,如果某个系统跳过了签名环节,直接用对称加密+哈希——那就是典型的不合规,直接扣分。

好了,这一章的基础回顾就到这。记住一句话:算法选对、密钥管好、随机数不瞎编——审计就能过八成。剩下的两成是流程和证据链,后面几章慢慢聊。