密码学基础回顾:对称/非对称加密、哈希、签名、密钥交换

密码学,说白了就是让不该看的人看不懂,让该看的人能验证真伪。

这套基础是PKCS#11的根基。你想想看,要是连这些概念都搞混,后面做接口集成肯定踩坑。我个人习惯是把密码学工具分为四类:加密、哈希、签名、密钥交换。今天咱们逐个拆开聊。

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

对称加密用同一个密钥做加密和解密。速度快,适合批量数据。我在项目中遇到过一个大坑:业务方想用AES-256加密几TB的日志,结果没算好性能开销,直接拖垮了数据库的IO。后来我们换成了AES-128-GCM,性能提升了一倍,安全性也没降多少。

核心要点

  • AES:目前最主流的对称算法。密钥长度有128、192、256位。
  • 模式:ECB(别用)、CBC(常用但需要IV)、GCM(推荐,自带认证)。
  • 流密码 vs 块密码:RC4是流密码,AES是块密码(128位一块)。

嗯,这里要注意ECB模式。同样的明文块会产生同样的密文块。举个例子,给一张企鹅图片用ECB加密,加密后还能看到企鹅轮廓。这哪叫加密啊?我建议项目里默认选GCM,除非你有特殊理由。


# Python 示例:AES-GCM 加密
from Crypto.Cipher import AES
import os

key = os.urandom(32)  # 256 位密钥
nonce = os.urandom(12)  # 96 位 nonce(推荐)
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
plaintext = b"This is sensitive data"
ciphertext, tag = cipher.encrypt_and_digest(plaintext)

# 解密时,需要 key, nonce, ciphertext, tag
cipher_dec = AES.new(key, AES.MODE_GCM, nonce=nonce)
data = cipher_dec.decrypt_and_verify(ciphertext, tag)

非对称加密:公钥私钥不分离

非对称加密用一对钥匙:公钥加密,私钥解密。公钥可以公开,私钥必须保密。速度慢,但解决了密钥分发问题。

我记得刚接触PKCS#11时,最困惑的就是密钥标签和密钥对的关联关系。每个密钥对都有一个唯一的句柄,私钥句柄通常不能直接导出,而公钥句柄可以。这个设计其实很合理——私钥一旦离开硬件安全模块,安全性就没了保证。

实践建议

非对称加密不要用来加密大文件。它适合加密对称密钥(比如AES密钥),或者用于数字信封。我见过一些新手直接用RSA加密几MB的文件,结果性能惨不忍睹。

算法 密钥长度 安全强度 典型用途
RSA 2048/4096 112/128位 加密小数据、签名
ECC 256/384 128/192位 移动设备、签名、密钥交换
SM2 256 128位 国密标准

哈希:不可逆的指纹

哈希函数把任意长度的数据变成固定长度的摘要。它不可逆——你不能从摘要反推出原文。两个关键属性:抗碰撞性(很难找到两个不同输入得到相同输出)和单向性。

避坑指南

我曾经被MD5坑过一次。当时做文件完整性校验,项目里用了MD5。结果发现攻击者可以在不改变MD5的情况下篡改文件(因为存在已知碰撞)。从那以后,任何新项目我都只推SHA-256或更高。

记住:MD5和SHA-1已经不安全了。现在最低标准是SHA-256。

哈希还有一个重要变种:HMAC(基于哈希的消息认证码)。它加了一把密钥,让只有知道密钥的人才能验证哈希的正确性。我建议你在API签名场景里优先用HMAC,而不是单纯的哈希。

签名:证明你是谁

数字签名是哈希+非对称加密的组合。流程是这样的:

  1. 对消息做哈希,得到摘要
  2. 用私钥加密这个摘要,得到签名
  3. 验证时,用公钥解密签名,得到摘要A;再对消息做哈希得到摘要B
  4. 如果A == B,说明消息没被篡改,而且确实是私钥持有者签的

你想想看,这个设计多巧妙。签名同时保证了真实性(确实是这个人签的)和完整性(消息没被改)。我在做硬件安全模块集成时,最常遇到的签名算法是RSA-PSS和ECDSA。RSA-PSS比PKCS#1 v1.5更安全,但兼容性稍差些。

密钥交换:怎么安全地拿到对方的公钥?

没有密钥交换,所有加密都无从谈起。最经典的协议是Diffie-Hellman (DH)。它能让你和另一个人在不安全的信道上,共同协商出一个只有你俩知道的对称密钥。

DH的问题是:它不验证身份。你无法确定你是在跟谁交换密钥。这就是中间人攻击的根源。解决方法是加入签名,或者用ECDH(椭圆曲线版本的DH),再配合证书链验证。

个人经验

在PKCS#11环境下做ECDH时,一定要检查私钥的访问控制属性。有一次我忘了设置CKA_SENSITIVE和CKA_EXTRACTABLE,结果私钥被意外导出,差点出了安全事故。现在我的习惯是:生成密钥时立刻锁定这些属性。

四大机制的对比

机制 密钥类型 可逆性 性能 主要用途
对称加密 对称密钥 可逆 快 加密大量数据
非对称加密 公钥/私钥对 可逆 慢 加密对称密钥、签名、数字信封
哈希 无密钥 不可逆 快 完整性校验、密码存储
签名 私钥签名/公钥验证 不可逆(摘要部分) 中等 身份认证、数据签名

这些就是密码学的基础工具。你不需要成为数学专家,但必须懂它们各自能做什么、不能做什么。后面我们做PKCS#11集成时,每一步都会用到这些概念。嗯,先把基础打牢,后面就不慌了。