RFC5802认证协议
RFC5802认证协议
提示
然而,在实际应用过程中,仅仅选定认证方法是不够的,还需要有一套完整的认证机制。
这个机制要很好地解决客户端和服务端认证交互过程中的通信风险,还要解决客户端接收到加密口令后的验证问题。
RFC5802 认证机制可以完美的解决这个问题。
RFC5802 认证机制实际上是SCRAM(Salted Challenge Response Authentication Mechanism,是指Salted质询响应身份验证机制或者基于盐值的质询响应身份验证机制)标准流程中的协议。
SCRAM 是一套包含服务器和客户端双向确认的用户认证体系,配合信道绑定可以避免中间人攻击。
协议内容
- 客户端知道用户名username和密码password,客户端发送username给服务端,服务端检索相应的认证信息,例如 salt、StoredKey、ServerKey 和迭代次数iteration-count(注意,服务端可能对于所有的用户都是用相同的迭代次数)。
然后,服务端发送盐值salt和迭代次数给客户端。 - 客户端需要进行一些计算,给服务端发送 ClientProof认证信息,服务端通过ClientProof对客户端进行认证,并发送ServerSignature给客户端。
- 客户端通过ServerSignature对服务端进行认证。
具体密钥计算公式如下:
SaltedPassword := Hi (password, salt, i) 其中,Hi()本质上是PBKDF2。
ClientKey := HMAC(SaltedPassword, "Client Key")
StoredKey := Hash(ClientKey)
AuthMessage := client-first-message-bare + "," +
server-first-message + "," +
client-final-message-without-proof
ServerKey := HMAC(SaltedPassword, "Server Key"
其中:
- AuthMessage:是通过连接认证交换的信息来计算的。
- client-first-message-bare:主要包含客户端给服务端发送的用户名username和随机字符串 C-Nonce。
- server-first-message: 主要是盐值 salt、迭代次数以及随机生成的字符串Nonce。
- client-final-message-without-proof:不包含认证信息 ClientProof,包含随机字符串 Nonce。
密钥衍生过程如下:
在这里,服务端存的是StoredKey和ServerKey。
- StoredKey: 用来验证客户端的客户身份,服务端认证客户端。通 过 计 算ClientSignature与客户端发来的 ClientProof进行异或运算,从而恢复得到 ClientKey, 然后将其进行哈希运算,将得到的值与 StoredKey进行对比。如果相等,证明客户端验证通过。
- ServerKey:用来向客户端表明自己身份,客户端认证服务端。通过计算 ServerSignature与服务端发来的值进行比较,如果相等,则完成对服务端的认证。
在认证过程中,服务端可以计算出 ClientKey,验证完后直接丢弃不必存储。 防止服务端伪造认证信息 ClientProof,从而仿冒客户端。
要做到合法的登录,必须知道Password、SaltedPassword或者 ClientKey。如果 StoredKey和 ServerKey泄露,则无法做到合法登录。
在一个认证会话期间的客户端和服务端的详细信息交换过程如下图所示:
- 客户端发送username和随机生成的挑战值 C-Nonce给服务端。
- 服务端返回盐值 salt、迭代次数以及随机生成的挑战值Nonce给客户端。Nonce是将从客户端收到的 C-Nonce和随机生成字符串组合形成的新挑战值。
- 客户端发送认证响应。响应信息包含客户端认证信息 ClientProof和挑战值Nonce。ClientProof证明客户端拥有 ClientKey,但是不通过网络的方式发送。在收到信息后,首先需要校验传来的挑战值 Nonce,校验通过后,计算 ClientProof。
客户端利用盐值salt和迭代次数,从password计算得到 SaltedPassword,然后通过密钥计算公式计算得到ClientKey、StoredKey和ServerKey。
计算AuthMessage: 通过将客户端首次发送的信息,服务端首次发送的信息以及客户端的响应信息(不包含认证信息)连接起来得到 AuthMessage。
AuthMessage := client-first-message-bare + "," +server-first-message + ","
+ client-final-message-without-proof
ClientSignature := HMAC(StoredKey, AuthMessage
客户端通过将ClientKey和ClientSignature进行异或得到ClientProof:
ClientProof := ClientKey XOR ClientSignature
将计算得到的ClientProof和第2步接收的随机字符串Nonce发送给服务端进行认证。
- 服务端认证 Nonce和 ClientProof,并且发送自己的认证信息 ServerSignature。
首先需要校验Nonce,校验通过后,计算 ServerSignature。使用其保存的StoredKey和AuthMessage通过 HMAC(HashMessageAuthenticationCode,哈希消息认证码) 算法进行计算,然后与客户端传来的ClientProof进行异或,恢复ClientKey,再对ClientKey进行哈希计算,得到的结果与服务端保存的 StoredKey进行比较。如果相等,则服务端对客户端的认证通过。
ClientSignature := HMAC(StoredKey, AuthMessage)
H(ClientProof XOR ClientSignature ) == StoredKe
- 服务端通过计算得到的ServerSignature返回给客户端。
ServerSignature := HMAC(ServerKey, AuthMessage)
- 客户端通过将ServerKey和AuthMessage进行 HMAC计算得到的ServerSignature 与服务端传来的 ServerSignature进行比较。如果相等,则客户端完成对服务端的认证。