日志格式规范 —— SM2密钥销毁日志长什么样
我记得刚接手审计系统时,第一个感觉就是:日志格式怎么这么乱?有的系统用 JSON,有的用 XML,时间戳有的带时区有的不带,字段名也不统一。后来我发现,真正成熟的密钥销毁日志,必须有一套严格的标准。否则审计人员拿到日志,根本没法解析,更别说验证签名了。
说白了,SM2密钥销毁日志的格式规范,就是给审计链打地基。地基不稳,后面全是坑。这一节我把核心要素拆开讲:标准字段、时间戳、签名方式、以及两种常见序列化结构。
标准字段都有哪些
一个合格的销毁日志,至少要包含以下字段。我用一张表列出来,你对照着看会清楚很多。
| 字段名 | 英文标识 | 说明 | 示例值 |
|---|---|---|---|
| 日志ID | log_id | 全局唯一,防重放 | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| 销毁时间 | destruction_time | UTC时间,精确到毫秒 | 2026-03-15T08:32:17.456Z |
| 密钥标识 | key_id | 被销毁密钥的SM2公钥哈希 | sm2-20260315-001 |
| 操作者 | operator | 执行销毁的用户或设备ID | admin@security |
| 销毁原因 | reason | 枚举值或描述 | 密钥到期 / 合规轮换 |
| 签名值 | signature | SM2签名(十六进制) | 3045022100... |
| 签名公钥 | signer_public_key | 签名者SM2公钥(PEM或Hex) | 04b7... (65字节) |
log_id。我在项目中遇到过因为日志ID不唯一,导致审计系统里出现两条一模一样的销毁记录,结果合规审查时被质疑日志造假。后来强制用UUID v4,再也没出过这种问题。
时间戳格式 —— 别让时区坑了你
时间戳看着简单,但坑最多。你想想看,系统A在上海,系统B在伦敦,如果日志里只写 2026-03-15 16:32:17,请问这是北京时间还是格林威治时间?审计人员根本没法判断。
我建议统一用 UTC ISO 8601,带毫秒和时区标识。例如:
2026-03-15T08:32:17.456Z
这里的 Z 表示 UTC。如果你偏要用偏移量,也可以:
2026-03-15T16:32:17.456+08:00
但无论如何,必须明确时区。我曾经在处理跨国密钥销毁日志时,因为时间戳没带时区,导致两次销毁事件的时间顺序错乱,差点被当成安全事件上报。后来我在代码里加了强制校验:非UTC或非明确偏移量的日志直接拒绝入库。
签名方式 —— 用SM2自证清白
日志一旦生成,怎么证明它是原始记录,没被篡改过?答案是:对日志内容进行SM2签名。
常见的做法是:先将日志的固定字段(除去签名本身)拼成一个待签名原文,然后用签名者的SM2私钥签出 (r, s) 值。接收方拿到日志后,用同样的方式拼出原文,再用公钥验签。
我习惯的拼装顺序是:
- log_id(UUID字符串)
- destruction_time(ISO 8601字符串)
- key_id
- operator
- reason
把这些字段用 || 分隔拼接成字符串(或者用TLV编码,但字符串拼接更简单)。然后做SM2签名,签名结果按ASN.1 DER编码,再转成十六进制字符串存入日志。
我曾经在验签时发现总失败,排查了半天,原来是拼接时多了一个空格。后来我明确规定:字段值之间不加任何分隔符,直接按固定顺序拼接。比如:
a1b2c3d4-e5f6-7890-abcd-ef12345678902026-03-15T08:32:17.456Zsm2-20260315-001admin@securitykey_expired。这样两边完全一致,签名自然就通了。
JSON / XML 结构 —— 两种马甲,一个内核
序列化格式方面,业界主要用 JSON 和 XML。JSON 轻量,XML 带命名空间和Schema校验,各有优势。我两个都给出例子,你根据自己系统的生态选一个就好。
先看 JSON 版本:
{
"log_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"destruction_time": "2026-03-15T08:32:17.456Z",
"key_id": "sm2-20260315-001",
"operator": "admin@security",
"reason": "key_expired",
"signer_public_key": "04b742...省略...",
"signature": "3045022100d89f...省略..."
}
XML 版本(带命名空间):
<?xml version="1.0" encoding="UTF-8"?>
<Sm2KeyDestructionLog
xmlns="urn:ietf:params:sm2:audit:1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<logId>a1b2c3d4-e5f6-7890-abcd-ef1234567890</logId>
<destructionTime>2026-03-15T08:32:17.456Z</destructionTime>
<keyId>sm2-20260315-001</keyId>
<operator>admin@security</operator>
<reason>key_expired</reason>
<signerPublicKey>04b742...省略...</signerPublicKey>
<signature>3045022100d89f...省略...</signature>
</Sm2KeyDestructionLog>
核心流程回顾
我把日志从生成到审计的流程画成一张图,方便你理解整体脉络。
整个流程并不复杂,但每个环节都有小的细节。比如时间戳格式、签名原文的拼装规则、序列化时字段的排序等等。只要你把这些规范定死,并在代码里用单元测试覆盖住,后面的审计链路跑起来就会很顺畅。