第2章:加密基础——对称加密、非对称加密、哈希

说到加密,很多刚入行的兄弟容易把这三种概念搞混。我当年第一次对接HSM时,就傻傻分不清对称和非对称的区别,结果密钥管理出了个大bug。今天咱们把这三种基础加密方式彻底理清楚。

说白了,加密就是让明文变成密文,只有有钥匙的人才能解密。哈希呢,不是加密,是摘要——给你一串固定长度的指纹,你无法反推原文。

2.1 对称加密

对称加密,加密和解密用的是同一把密钥。就像你用一把锁锁箱子,还是这把钥匙开箱子。

个人习惯:我通常把对称加密叫"一把钥匙走天下"。效率高,适合大批量数据加密。

常用算法:

算法密钥长度分组模式典型场景
AES128/192/256 bitECB / CBC / GCM文件加密、TLS
SM4128 bitECB / CBC / CTR国密合规场景
3DES168 bit(实际有效112)ECB / CBC遗留系统兼容(不推荐)

需要注意的点:

  • 密钥分发是个大坑。我有个项目,因为同事把AES密钥明文写在配置文件里,被甲方安全审计打了个不及格。
  • ECB模式不安全。同样的明文字块会得到同样的密文,容易被统计分析。我建议至少用CBC。
  • GCM模式自带认证,能防篡改,适合网络传输。
避坑指南:我曾经遇到过一个案例,项目把AES密钥直接存数据库但不加密。结果数据库泄露,所有用户数据相当于裸奔。对称密钥必须放在HSM里或加密存储。

2.2 非对称加密

非对称加密,用一对密钥:公钥加密,私钥解密。公钥可以公开,私钥必须保密。

你想想看,这样就不需要像对称加密那样费劲去安全传递密钥了。我刚开始觉得这玩意儿完美,后来才发现它有性能问题——加解密慢得一批,通常只用来加密对称密钥本身。

常见算法对比:

算法密钥长度性能推荐
RSA2048/4096 bit较慢,密钥越长越慢兼容性好,通用
ECC256 bit(等效RSA 3072)快,密钥短移动端、IoT推荐
SM2256 bit与ECC相当国密标准

常用场景:

  • 密钥协商: 客户端用服务器公钥加密一个随机生成的对称密钥,服务器用私钥解密。后续用这个对称密钥通信。
  • 数字签名: 私钥签名,公钥验签。用来保证数据来源和完整性。

个人经验: 在HSM中做非对称运算时,一定要确认HSM支持的模式。有的HSM要求私钥在硬件内部生成,不导出来。我曾经图省事在软件端生成密钥对再导入HSM,被安全评审打回。

2.3 哈希

哈希不是加密,是单向函数。输入任意长度,输出固定长度的摘要。你无法从摘要反推原文。

常用哈希算法:

  • SHA-256: 最常用,输出256位。我见过99%的项目用这个。
  • SM3: 国密哈希,输出256位,算法设计上基本等效SHA-256。
  • MD5: 输出128位,已破解,别用了。
注意: 哈希没有密钥。如果有人跟你说"用哈希加密数据",那是不对的。哈希只是验证完整性,不能解密。我曾经在代码评审里见过有人把用户密码用MD5存数据库,还以为是加密……结果数据库被拖,彩虹表一秒还原。

哈希的典型用法:

  • 密码存储: 必须加盐(salt),然后用慢哈希算法(如bcrypt、PBKDF2)。不能直接用SHA-256。
  • 消息完整性: 发送数据的同时发哈希值,接收方重新计算比对。
  • 数字签名: 先对消息做哈希,再对哈希签名。效率高。
建议: 我个人习惯在做HMAC(基于哈希的消息认证码)时,密钥长度不低于哈希输出长度。比如SHA-256就用至少32字节的密钥。这是对照NIST指南的。

2.4 三种技术的核心关系

这三者在实际系统中是配合使用的。最经典的模式是:

  1. 用非对称加密传递对称密钥(安全分发)。
  2. 用对称密钥加密大批量数据(高效)。
  3. 用哈希验证数据是否被篡改(完整性)。
  4. 用非对称签名保证数据来源(真实性)。

下面这张图概括了它们之间的关系:

加密基础:三大核心技术关系图 对称加密 同一密钥 加/解密 非对称加密 公钥加密 私钥解密 哈希/摘要 单向函数 不可逆 高效,适合大批量 安全分发 对称密钥 混合加密(真实场景) 非对称加密传递临时对称密钥 → 对称加密数据 → 哈希验证完整性 数据完整性校验 密码存储 哈希+盐,慢算法 数字签名 私钥签名,公钥验签 TLS/SSL 证书链+混合加密+哈希

你看,这三种技术不是互相替代的,而是各司其职。在HSM对接中,我们会大量用到它们:对称密钥在HSM内部生成并存储,非对称密钥对由HSM硬件保护,哈希运算也在HSM内计算(特别是SM3/SHA-256硬件加速)。

实战提醒: 我第一次做HSM对接时,觉得哈希简单,直接在应用层用OpenSSL算了哈希再发给HSM做签名。后来发现这样不安全——HSM签名的是应用传来的哈希值,如果中间人篡改了哈希,HSM也无法察觉。正确的做法是:把整个原始消息发给HSM,让HSM内部先做哈希再签名。这是安全边界的问题,很多新手会踩这个坑。