第2章 密码学基础与国密算法简介

密码学这东西,我在刚开始做审计日志的时候总觉得是“别人的事”。后来被客户问了一句“你的日志签名用的什么算法”,我才意识到不懂密码学根本没法设计可靠的审计系统。说白了,审计日志的安全根基,就扎在密码学算法上。

这一章我们只聊最核心的东西:对称/非对称加密、哈希函数,以及国密 SM2、SM3、SM4 的原理和用法。不废话,直接上干货。

2.1 密码学基础回顾

我习惯把密码学的基础分成三块,你想想看,所有安全场景都离不开它们:

  • 对称加密:加密和解密用同一个密钥。快,适合大量数据。
  • 非对称加密:有公钥和私钥,公钥加密私钥解密。慢,适合密钥交换和数字签名。
  • 哈希函数:把任意长度数据变成固定长度的摘要。不可逆,用于完整性校验和密码存储。
我在项目中见过一个坑:有人用 MD5 做日志完整性校验,后来被撞库攻破了。记住,哈希算法要选抗碰撞能力强的,比如 SM3。

2.2 国密算法概览

国密算法是国家密码管理局发布的标准,在审计日志场景中,我用得最多的是这三个:

算法 类型 密钥长度 主要用途(审计日志中)
SM2 非对称加密(椭圆曲线) 256 位 数字签名、日志签名、密钥协商
SM3 密码杂凑 输出 256 位 日志完整性哈希链、消息摘要
SM4 对称分组密码 128 位 日志内容加密、密钥传输加密

为什么要用国密?合规是硬性要求。但更重要的是,它们的密码学强度经过严格论证,我个人觉得在同等安全级别下,SM2 的椭圆曲线比 RSA 更轻量,SM3 比 SHA-256 更安全,SM4 的硬件实现效率也很高。

2.3 算法原理简析

SM2

SM2 基于椭圆曲线离散对数问题。它的核心是:给定基点 G 和公钥 Q = d·G(d 是私钥),想从 Q 反推 d 极难。签名时,用户用私钥对消息哈希做运算,验证者用公钥验签。我曾经在改造一个老系统时,遇到签名长度变长的问题(SM2 签名是 64 字节,而 RSA 签名是 128 字节),反而节省了存储空间。

SM3

SM3 是密码杂凑算法,输出 256 位。算法结构类似 SHA-256,但增加了更复杂的消息扩展和压缩函数,抗碰撞性更强。在审计日志中,我常用 SM3 构造哈希链——每条日志记录包含前一条的 SM3 哈希值,这样任何篡改都会破坏链的连续性。

SM4

SM4 是 128 位分组密码,密钥长度也是 128 位。它采用 Feistel 结构,轮函数包含非线性变换(S 盒)和线性变换。加密速度非常快,适合加密大规模的日志数据。注意分组密码需要选择合适的工作模式,比如 GCM(伽罗瓦计数器模式)可以同时提供机密性和完整性校验。

关键点:在审计日志设计中,绝不使用 ECB 模式。同样的明文会得到同样的密文,攻击者能看出日志模式。我遇到过用 ECB 加密日志的场景,后期不得不全部重做。

2.4 在审计日志场景中的应用

把这些算法组合起来,就能搭建一套可靠的审计日志保护体系:

  1. 日志签名:使用 SM2 私钥对每条日志的 SM3 摘要签名,验证方用公钥验签。防伪造和抵赖。
  2. 日志加密:使用 SM4 对称密钥加密日志正文,然后用 SM2 公钥加密这个对称密钥(混合加密)。兼顾速度和安全性。
  3. 完整性链:每条日志的 SM3 摘要包含上一条日志的摘要,形成链式结构。任何篡改都会断裂。

我曾经犯过一个错:把 SM3 哈希和签名直接拼到一起,结果签名过程中哈希值被意外修改,导致验签失败。正确的做法是先计算 SM3 摘要,再对摘要签名,签名时要保证摘要不被中途篡改。

2.5 核心关系图

下面这张图帮你理清密码学基础与国密算法在审计日志中的角色:

密码学基础与国密算法在审计日志中的应用 对称加密 非对称加密 哈希函数 SM4 SM2 SM3 加密日志正文 数字签名 完整性哈希链 核心:SM4 用作对称加密,SM2 用作公钥签名,SM3 构建哈希链 三者组合实现审计日志的机密性、完整性和不可抵赖性

2.6 几个实用建议

  • 密钥管理比算法本身更重要。我曾经见过一家公司 SM2 私钥硬编码在配置文件里,直接用明文保存。再强的算法也白搭。
  • SM4 一定要用认证加密模式,比如 GCM 或 CCM。审计日志如果只加密而不校验完整性,攻击者可以替换整个密文。我有一次安全审计就发现了这个问题。
  • 哈希链的节点要包含时间戳和顺序号,否则单纯链式哈希容易遭到重放攻击。我习惯在每条日志的 SM3 输入中加入“前一条哈希 + 时间戳 + 日志内容”。
  • 签名操作要原子化:计算哈希、签名、写入日志这三步必须是一个事务。失败就回滚,避免产生半条签名的日志。

我个人习惯在开发阶段先用 OpenSSL 测试国密算法的正确性,再用 GMSSL 或腾讯的国密库做生产部署。很多 bug 在算法封装层就能发现,别等上线再排查。