安全远程密码协议,用于在不安全的环境中进行密钥交换,同时支持零知识进行身份认证。零知识认证指的是客户端向服务器证明自己知道密码,但是不需要向服务器发送密码来验证自己的身份。在完成密钥交换和身份认证过程中,密码永远不会离开客户端,即使有攻击者窃听到交互的信息,也不能反向推导出机密信息。
SRP协议的设计
根据【1】的定义,SRP消息交互流程如下所示:
SRP-6 和 6a 中的符号定义:
N: 安全大素数(N = 2q+1,其中 q 为素数)。所有算术运算都是以 N 为模进行的。
g: 一个模 N 的生成器
H(): 单向哈希函数
k: 乘数参数(SRP-6a 中为 k = H(N, g),传统 SRP-6 中为 k = 3)
s: 用户的盐值
I:用户名
p: 明文密码
v: 用户的密码验证器,v = g ^ x,其中最小值为x = H ( s , p )。由于x仅在客户端上计算,因此可以自由选择更强大的算法。实现可以选择使用x = H ( s | I | p ),而不会影响主机所需的任何步骤。标准RFC2945定义了x = H ( s | H ( I | ":" | p ) ) 。在x中使用I可避免恶意服务器能够获知两个用户是否共享相同的密码
a,b: 不公开的随机值
A,B: 由a,b生成的公开的临时值,在消息中交换
A = g ^ a
B = g ^ b + k * v
u: 随机加扰参数
标准RFC2945定义:一个 32 位无符号整数,其值取自 B 的 SHA1 哈希值的前 32 位(MSB 优先);
其他定义:u = H(A, B)
x: 私钥(源自 p 和 s)
标准RFC2945定义:x = H(s | H(I | ":" | p)
K: Session通信加密密钥
客户端计算:S = (B - k * g ^ x) ^ (a + ux) = ((g ^ b + k * v) - k * g ^ x) ^ (a + ux) = (g ^ b) ^ (a + ux),K = H(S)。
服务器端计算:S =(Av ^ u) ^ b = (g ^ a (g ^ x) ^ u) ^ b = (g ^ (a+ux)) ^ b,K = H(S)。
M: 身份认证标识
客户端->服务器:Mclient = H(H(N) xor H(g), H(I), s, A, B, K)。
服务器->客户端:Mserver = H(A, Mclient, K)。
| (管道)表示字符串连接
- 用户注册阶段:
- 客户端和服务端协商好相关参数,服务端建立I -> (N, g, s, v)的映射。
- 密钥协商阶段:
不同的实现消息流程和携带参数略有不同,这里参照【1】的定义。
- 用户发起请求,携带参数用户名(I),随机生成的(A)。
- 服务端返回该用户名对应的盐(s)和生成的(B)。
同时,两端按照通信密钥定义的算法,分别计算密钥。
- 身份认证阶段:
双方使用计算出的密钥,加密接下来的消息。
- 用户向服务端发送Mclient,服务端进行验证。
- 服务端向用户发送Mserver,客户端进行验证。
异常处理:
- 如果用户收到 B == 0 (mod N) 或 u == 0,则用户将中止。
- 如果服务器检测到 A == 0 (mod N),它将中止。
- 用户必须先出示自己的 K 证明。如果服务器检测到用户的证明不正确,则必须中止,而不出示自己的 K 证明。
从密钥的交互算法看,SRP与Diffie–Hellman很类似,但是对B的计算进行了一定的增强。
支持SRP的应用与协议
1Password密钥管理工具已使用 SRP 来验证身份。
SRP协议被用于SSL/TLS中的强密码身份验证(TLS-SRP)、EAP、SAML等标准,以及IEEE 1363.2和ISO/IEC 11770-41。不过从【4】中可知,TLS1.3并不包含SRP的支持。从维基百科【2】介绍可以知道,SRP的第一个版本到现在已经经历了20多年了,虽然历经几个版本的演进修订了一下安全缺陷,【4】建议是使用增强的认证密钥协商协议,如CPace或者OPAQUE。