密码学基础回顾:对称加密、非对称加密、哈希与数字签名

各位好,我是老张。做审计日志加密验证这个行当,密码学基础就像地基。你今天绕过的坑,明天都会在日志里加倍还回来。这一章我带大家快速过一遍核心概念,不扯太多数学公式,只讲“为什么这样设计”以及“我在项目中踩过的雷”。

对称加密:一把钥匙开一把锁

对称加密,说白了就是加密和解密用同一把密钥。你想想看,如果两个人要用秘密通道传消息,必须先偷偷见一面,把钥匙互换。AES(高级加密标准)是目前最常用的对称算法,分AES-128、AES-192、AES-256,密钥越长越安全。

核心参数:
  • 密钥长度:128 / 192 / 256 位
  • 分组大小:128 位(16字节)
  • 工作模式:ECB、CBC、GCM 等

我早年做嵌入式日志加密时,图省事用了ECB模式。结果呢?相同明文块加密后结果一模一样,攻击者一看就知道哪些日志内容是重复的。后来乖乖改成CBC加随机IV,或者直接用GCM(认证加密模式)。

避坑:不要用ECB模式加密日志块。我曾见过一个项目因为ECB模式导致日志时间戳模式暴露,被攻击者推测出业务峰值。GCM自带认证标签,能同时防篡改,推荐优先使用。
AES常见工作模式对比
模式 是否需要IV 并行加解密 认证保护
ECB 否 是 无
CBC 是(随机) 仅解密 无
GCM 是(随机) 是 有(GMAC)

代码层面,使用OpenSSL的AES-GCM示例如下(C语言):

EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, iv);
EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, ptlen);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
EVP_CIPHER_CTX_free(ctx);

非对称加密:两把钥匙的巧妙配合

非对称加密解决了对称加密的“密钥分发”难题。公钥随便发,私钥自己藏。RSA和椭圆曲线(EC)是两大主流。RSA基于大整数分解,EC基于椭圆曲线离散对数——后者密钥短、性能高,现在越来越流行。

我的经验:RSA-2048和ECDSA-P256安全级别相当。但RSA签名验证慢,EC签名更快。做审计日志数字签名时,如果日志量大、CA频率高,我建议用ECDSA。不过注意,EC曲线必须用标准曲线(如P-256, P-384),不要自己发明。

实际应用中的经典场景:

  • 加密密钥交换:用接收方公钥加密会话密钥,只有私钥持有者能解密。
  • 数字签名:发送方用私钥签名,接收方用公钥验签,确保数据来源和完整性。
曾经踩过的坑:在PKCS#11 上做RSA签名时,必须确认协商的填充方式。PKCS#1 v1.5填充有已知漏洞(Bleichenbacher攻击),建议使用RSA-PSS。我调过一个老旧HSM,默认用v1.5,差点通过不了PCI-DSS审计。

哈希函数:不可逆的指纹

哈希函数把任意长度数据压缩成固定长度摘要,且不可逆。SHA-256输出256位,是当前审计日志中最常见的哈希算法。MD5和SHA-1已经不够安全,别再用了。

哈希的核心特性:

  1. 抗原像性:给定哈希值,几乎不可能反推出原文。
  2. 抗弱碰撞:给定原文,找不到另一篇原文哈希值相同。
  3. 抗强碰撞:找不到任意两篇不同原文哈希值相同(更难满足)。

哈希在审计日志里主要用来做完整性校验——把日志内容算一个摘要存储,事后重新计算对比,就知道有没有被篡改过。我遇到过案例:攻击者删除了几行日志后,没有重新计算后面的哈希链,导致日志链断裂被审计发现。所以哈希链(每个日志块包含前一个块的哈希)是基础防护。

数字签名:哈希 + 非对称加密的完美组合

数字签名不是“加密”,而是用私钥对哈希值做签名。好处是:签名者不能抵赖(不可否认性),内容没被改过(完整性),并且能确认身份(真实性)。

工作流程清晰:

  • 发送方:原文 → SHA-256 → 摘要 → 私钥签名 → 签名值
  • 接收方:原文 → SHA-256 → 新摘要 + 公钥验签 → 比对摘要
注意:数字签名不加密原文。审计日志中原始日志内容通常还是明文存储(或对称加密),但会加一个数字签名用于验证。签名本身很短(RSA-2048签名256字节,ECDSA-P256约64字节),不会显著增加存储开销。

在PKCS#11环境里,签名操作通过C_Sign / C_Verify系列函数完成。下面是一个ECDSA签名的简化示例(伪代码):

CK_SESSION_HANDLE hSession;
CK_OBJECT_HANDLE hPrivKey;
CK_BYTE data[] = "审计日志内容";
CK_BYTE signature[64];
CK_ULONG sigLen = sizeof(signature);

// 初始化签名
C_SignInit(hSession, &ecdsa_mech, hPrivKey);
// 签名(内部会先哈希,再签名)
C_Sign(hSession, data, dataLen, signature, &sigLen);

这里用的是CKM_ECDSA机制,它默认使用SHA-256进行哈希。如果你选的机制不支持自动哈希,需要先手动计算哈希再传进去。

知识结构总览

下面这张SVG图把这四个密码学模块的关联画出来了。箭头代表数据流向,你可以直观看到数字签名如何融合哈希和私钥。

密码学基础四模块关系图 对称加密 AES-128/256 非对称加密 RSA / ECDSA 哈希函数 SHA-256 数字签名 哈希 + 私钥签名 = 不可否认 公钥加密,私钥解密 摘要 → 完整性校验 数字签名 = 使用私钥对哈希摘要进行签名,公钥验签 对称加密用于日志内容加密,非对称加密用于密钥分发和签名
一句话总结:做审计日志加密验证,你只需要记住——对称加密保机密,哈希保完整性,数字签名保真实与不可否认。非对称加密在这中间充当钥匙管理员的角色。

好了,这一章的基础铺垫就到这。后面我们会把这四个模块用到PKCS#11的各种机制里。嗯,先消化一下,有问题随时在工作群里问我。