你能向别人证明你知道一个秘密,但完全不用透露这个秘密本身。这就是 SRP 协议的魔力。
前情回顾
在前两篇中,我们看到了密码存储的进化:
- MD5:太快,彩虹表秒破
- Argon2:慢哈希 + 吃内存,大幅提高破解成本
但即使用了 Argon2,有一个根本问题没解决:密码仍然要传到服务器上。
服务器会"看到"你的密码,哪怕只是短暂的一瞬间。如果服务器被黑客控制、如果有恶意管理员、如果内存被 dump……密码仍可能泄露。
有没有办法让服务器永远不知道你的密码,却仍能验证你的身份?
答案是:SRP 协议。
从一个问题说起
每次你在网站上输入密码登录时,发生了什么?
传统登录方式
- 你的设备 → 服务器:发送用户名 + 密码(明文)
- 服务器验证密码哈希
- 服务器 → 你的设备:登录成功/失败
问题:密码在网络上传输,服务器能看到密码
这个过程有一个根本性的问题:你的密码被发送到了网站服务器。
这意味着:
- 如果网络被监听,密码可能泄露
- 如果网站被黑客攻破,密码可能泄露
- 如果网站管理员是坏人,他能看到你的密码
- 如果你在多个网站用同一个密码(别装了,很多人都这样),一个网站泄露 = 全部泄露
一个生活中的类比
想象特工电影里的"对暗号"场景。
传统对暗号:
甲:“天王盖地虎” 乙:“宝塔镇河妖”
问题:暗号直接说出口,被窃听就泄露了。
SRP 风格的对暗号:
注册阶段(你和总部建立联系):
- 你的密码是"玫瑰"
- 你用"玫瑰"生成一个数学规则,告诉总部
- 总部存储这个"规则",但不知道你的密码是"玫瑰"
验证阶段(每次接头):
- 特工 → 总部:“我是 007,随机数 37”
- 总部 → 特工:“好的,随机数 82”
- 特工用 “玫瑰” + 37 + 82 计算出 9527
- 总部用 规则 + 37 + 82 计算出 ???
- 双方比对:9527 == 9527 ? → 验证成功!
密码"玫瑰"从未被说出口,但成功证明了身份
为什么这样更安全?
窃听者听到了什么?
- 随机数 37 和 82
- 结果 9527
窃听者能推出密码吗?不能!
- 37、82、9527 之间的数学关系极其复杂
- 而且下次的随机数完全不同,9527 也没法重放
这就是 SRP 的核心思想:双方各自计算,如果密码正确,结果相同。密码本身从未传输。
SRP 是什么?
SRP(Secure Remote Password,安全远程密码)是 1998 年由斯坦福大学的 Tom Wu 发明的协议。它让你能够:
- 证明你知道密码,但密码永远不离开你的设备
- 服务器验证你的身份,但服务器从不知道你的真实密码
- 建立加密通道,后续通信完全加密
SRP 的工作原理(简化版)
第一步:注册(只发生一次)
当你在网站注册账号时:
客户端操作:
- 输入密码 “MySecret123”
- 生成随机盐值
salt - 计算验证器:
x = H(salt, password),v = g^x mod N
客户端 → 服务器: 发送 username, salt, v(密码本身从不发送!)
服务器存储: username, salt, v (验证器)
注意:服务器存储的 v 无法反推出密码,即使数据库泄露,攻击者也无法直接得到密码。
第二步:登录(每次都这样)
登录过程像一场精心设计的"数学对话":
Step 1: 客户端准备
- 生成随机数
a,计算A = g^a
Step 2: 客户端 → 服务器 发送 username, A
Step 3: 服务器处理
- 查找用户,获取
salt, v - 生成随机数
b,计算B = kv + g^b
Step 4: 服务器 → 客户端 返回 salt, B
Step 5: 双方各自计算会话密钥
- 客户端:
x = H(salt, password),S = (B-kv)^(a+ux),K = H(S) - 服务器: 使用
v, A, b计算S = (Av^u)^b,K = H(S)
Step 6: 客户端 → 服务器 发送 M1 = H(A,B,K) (客户端证明)
Step 7: 服务器验证 M1
Step 8: 服务器 → 客户端 返回 M2 = H(A,M1,K) (服务器证明)
结果:双方共享密钥 K,可以加密通信。密码从未在网络上传输,中间人无法获得任何有用信息。
整个过程中,密码始终没有离开你的设备!
为什么 SRP 是安全的?
让我们看看各种攻击者能得到什么:
场景 1:黑客监听网络
黑客在客户端和服务器之间监听,记录了所有通信:
- 客户端 → 服务器:
A - 服务器 → 客户端:
salt, B - 客户端 → 服务器:
M1 - 服务器 → 客户端:
M2
黑客得到了什么?
- A, B (随机值)
- salt (随机值)
- M1, M2 (证明)
黑客能做什么?
- 无法算出密码
- 无法算出会话密钥
- 无法冒充任何一方
- 重放攻击无效(每次随机数不同)
结论:网络监听无效
场景 2:黑客攻破了服务器数据库
服务器数据库被攻破
| username | salt | verifier (v) |
|---|---|---|
| alice | x7k2m | 7a8b9c… |
| bob | p9n3q | 4d5e6f… |
黑客得到了什么?
- salt (盐值)
- v (验证器)
黑客能做什么?
由于 v = g^x mod N,可以离线暴力猜测密码:
- 遍历字典中的每个密码
pwd - 计算
x' = H(salt, pwd) - 计算
v' = g^x' mod N - 如果
v' == v,破解成功
但计算 g^x mod N 比普通哈希慢。
对比传统方案
| 方案 | 数据库泄露后 |
|---|---|
| 传统 (Argon2) | 得到哈希后可离线暴力破解,Argon2 靠"慢+吃内存"增加破解成本 |
| SRP | 得到验证器后仍可离线暴力破解,离散对数计算增加了一些成本,但仍可行 |
结论:数据库泄露后,仍可离线破解(这是 SRP 的局限)
场景 3:黑客同时监听网络 + 攻破数据库
黑客同时获得:
从网络监听:
- A, B (随机值)
- salt, M1, M2
从数据库泄露:
- salt, v (验证器)
组合所有信息后:
仍然面临离散对数难题:
- 已知: g, N, v, A, B
- 求: x (推导出密码)
可以离线暴力猜测:计算 v' = g^H(salt,pwd),与 v 比对。
结论:双重攻击时,可进行离线暴力破解。SRP 的主要优势在于密码不传输,而非防离线破解。
SRP vs 传统密码方案
| 对比项 | 传统方案 (Argon2) | SRP |
|---|---|---|
| 密码是否传输 | ✅ 是,每次登录都传 | ❌ 从不传输 |
| 服务器知道密码吗 | ✅ 知道(短暂接触密码或其哈希) | ❌ 永远不知道 |
| 网络监听能偷到密码吗 | ✅ 可能(依赖 HTTPS) | ❌ 不可能 |
| 数据库泄露能离线破解吗 | ⚠️ 可以(暴力破解哈希) | ⚠️ 可以(暴力破解验证器) |
| 需要依赖 HTTPS 吗 | ✅ 强依赖 | ⚠️ 防被动监听,但主动 MITM 仍需 TLS |
SRP 的实际应用
SRP 已经在很多地方被使用:
- 苹果 iCloud:保护你的 Apple ID
- 1Password:知名密码管理器
- ProtonMail:加密邮件服务
- 很多企业内部系统:金融、医疗等高安全场景
SRP 的局限性
虽然 SRP 很强大,但它不是万能的:
- 实现复杂:比普通密码系统复杂得多,容易实现出错
- 不能防止弱密码:如果你的密码是"123456",暴力破解仍然容易
- 需要客户端配合:浏览器/App 必须实现 SRP 逻辑
- 仍需 TLS 保护:SRP 可防止被动监听,但主动中间人攻击(MITM)仍需要 TLS/HTTPS 来防御
- 有更新的替代方案:OPAQUE 协议提供了更强的安全保证
技术细节(给好奇的读者)
SRP 的数学基础是离散对数问题:
核心数学问题:离散对数
正向计算(容易):
- 已知: g, x, N
- 求:
v = g^x mod N - 即使 x 是很大的数,计算机也能快速算出 v
反向计算(困难):
- 已知: g, v, N
- 求:
x = log_g(v) mod N - 这是"离散对数问题",目前没有已知的高效算法
- 当 N 足够大时(如 2048 位),破解需要天文数字的时间
SRP 参数说明
| 参数 | 含义 | 说明 |
|---|---|---|
| N | 大质数 | 通常 2048 位或更大 |
| g | 生成元 | 通常是 2 或 5 |
| k | 乘数参数 | k = H(N, g) |
| s | 盐值 | 随机生成 |
| x | 私钥 | x = H(s, password),仅用户知道 |
| v | 验证器 | v = g^x mod N,服务器存储 |
| a, b | 临时随机数 | 每次会话不同 |
| A, B | 临时公钥 | A = g^a, B = kv + g^b |
| S | 会话密钥前身 | - |
| K | 最终会话密钥 | K = H(S) |
安全性来源
- 离散对数问题保证:从 v 无法反推 x
- 临时随机数保证:每次会话密钥不同,无法重放
- 双向证明保证:服务器也要证明自己知道 v
- 密钥派生保证:K = H(S),会话密钥无法从其他信息推导
登录时的数学交换确保:
- 只有知道 x(即知道密码)的人才能计算出正确的会话密钥
- 窃听者无法从 A、B、M1、M2 反推出 x
- 服务器无法从 v 反推出 x
总结
SRP 协议实现了一个看似不可能的目标:让你证明你知道密码,而不用透露密码本身。
它就像一个精心设计的数学魔术:
- 你和服务器进行一场"数学对话"
- 如果你知道正确的密码,对话会成功
- 任何旁观者都无法从对话中得到有用信息
- 服务器从始至终不知道你的密码是什么
这就是现代密码学的魅力——用数学的力量,保护我们的数字生活。
但 SRP 还有一个隐藏的弱点:服务器存储的"验证器"仍然与密码相关。如果数据库泄露,攻击者仍可以离线暴力破解。
有没有办法让数据库泄露也无法离线破解?下一篇我们介绍 OPAQUE 协议——它把暴力破解从"离线"逼到"在线"。
上一篇:Argon2:慢哈希的艺术 下一篇:OPAQUE:防离线破解的终极方案
本系列:
- MD5:一部血泪史
- Argon2:慢哈希的艺术
- SRP:证明你知道密码却不说出密码(本篇)
- OPAQUE:防离线破解的终极方案
延伸阅读:零知识证明、Diffie-Hellman 密钥交换