2. 身份认证:从口令到零知识证明

身份认证,说白了就是回答一个问题:「你怎么证明你是你?」

我做了十几年安全协议,见过太多认证被绕过的案例。很多系统不是被攻破的,而是被「混进去」的。这一章,我们就把四种主流认证方式掰开揉碎讲清楚。

2.1 基于口令的认证

这是最古老、也最容易被骂的方式。用户输入用户名+密码,服务端比对哈希值。

核心流程:
  1. 用户注册时,服务端存储 H(password || salt),而不是明文密码。
  2. 登录时,用户发送 H(password || salt),服务端比对。
  3. 传输层必须使用 TLS,否则中间人可以截获哈希值直接重放。

我在项目中遇到过一件事:某团队自己实现了「加盐哈希」,但盐值是固定的「123456」。你想想看,这和没加盐有什么区别?

避坑指南:我曾经见过一个系统,用 MD5 哈希密码,而且没有加盐。攻击者拿到数据库后,彩虹表一跑,80% 的密码直接暴露。现在至少要用 bcrypt、scrypt 或 Argon2,并且每个用户的盐值必须随机生成。
算法 抗暴力破解 抗 GPU 加速 推荐场景
MD5 极差 极差 不要用
SHA-256 一般 差 完整性校验
bcrypt 好 好 Web 应用
Argon2 优秀 优秀 新系统首选

2.2 基于证书的认证

证书认证,本质上是「我不认识你,但我认识给你发证的人」。PKI(公钥基础设施)就是干这个的。

我习惯把证书比作身份证:CA 是公安局,证书是你的身份证,私钥是你的指纹。你出示身份证,别人验证公安局的签名,就能确认你的身份。

个人经验:证书认证最容易被忽略的是吊销检查。很多系统只验证证书签名和有效期,但从不检查 CRL 或 OCSP。结果就是:证书已经泄露了,系统还在信任它。

证书认证的典型流程:

  1. 客户端出示证书(包含公钥和 CA 签名)。
  2. 服务端验证 CA 签名是否可信。
  3. 服务端生成随机数,要求客户端用私钥签名。
  4. 服务端用证书中的公钥验证签名。

为什么会这样设计?因为证书可以公开,但私钥必须保密。攻击者即使拿到证书,没有私钥也伪造不了签名。

2.3 多因素认证

多因素认证,就是把「你知道的」「你拥有的」「你本身的」组合起来。

因素类型 示例 风险
知识因素 密码、PIN 码 容易被钓鱼、撞库
持有因素 手机、硬件 Token 可能丢失、被克隆
生物因素 指纹、人脸 不可撤销、可能被伪造

我个人建议:至少使用两个不同因素。比如密码(知识)+ TOTP(持有)。

避坑指南:我曾经见过一个系统,号称实现了多因素认证,但第二个因素只是向用户邮箱发送验证码。攻击者只要攻破邮箱,就能绕过所有认证。真正的多因素,必须来自不同的「域」。

2.4 零知识证明入门

零知识证明,听起来很玄乎,其实核心思想很简单:「我能证明我知道某个秘密,但我不告诉你这个秘密是什么。」

举个例子:我告诉你我有两把钥匙能打开一扇门,但我只给你看我从门里走出来,而不给你看钥匙本身。你相信了我有钥匙,但你没看到钥匙。

零知识证明需要满足三个条件:

  1. 完整性:如果我说的是真的,我一定能让你相信。
  2. 可靠性:如果我说的是假的,我无法让你相信。
  3. 零知识性:你除了「我说的是真的」之外,学不到任何其他信息。
实际应用场景:
  • 身份认证:证明我知道私钥,但不泄露私钥。
  • 区块链:证明交易合法,但不暴露交易细节。
  • 密码学协议:证明我遵守了协议规则,但不暴露输入数据。

嗯,这里要注意:零知识证明的计算开销通常很大。我建议只在需要强隐私保护的场景使用,比如金融交易、身份验证等。普通的 Web 登录,用证书认证就够了。

身份认证知识体系 身份认证 口令认证 证书认证 多因素认证 零知识证明 加盐哈希 暴力破解防护 PKI 体系 吊销检查 完整性·可靠性·零知识性 选择建议 普通场景:证书认证 高安全:多因素+零知识

这张图把四种认证方式的关系和子知识点串起来了。你可以看到,零知识证明是独立的一支,它不依赖任何中心化设施,但计算开销最大。

我的建议:在实际项目中,不要盲目追求「最安全」的方案。口令认证+多因素,已经能挡住 99% 的攻击。零知识证明很好,但除非你的场景对隐私有极端要求,否则先别上。