简介
SCRAM是一套包含服务器和客户端双向确认的用户认证体系,配合信道加密可以比较好的抵御中间人、拖库、伪造等攻击。
主要参考自SCRAM的流程
信道应另外加密以增强安全性,如使用可靠
TLS
方法实现的HTTPS
加密。
相关字段
定义:
Hash(content)
指安全Hash函数,如SHA256。HMAC()
指使用Hash(content)
作为基础实现的HMAC函数,如HMAC(SHA256,Key,Content)
。UserIdentify
:仅用于登录签名的用户身份标识字符串,每次登录时可根据业务任意选用用户名、手机号、邮箱、三方ID等,下次登录可以选另一种,仅作为本次通讯的标识之一使用。Password
= Hash(明文密码)Salt
:随机生成的盐。Iteration
:加盐计算时的迭代次数。SaltedPassword
= pbkdf2(Password
,Salt
,Iteration
),已加盐的密码。ClientNonce
:客户端在Step1时随机生成的字符串,用于对本次交互签名。ServerNonce
:服务器在Step1时随机生成的字符串,用于对本次交互签名。MixNonce
=ClientNonce
|ServerNonce
,ClientNonce
和ServerNonce
的按位或结果。ServerPub
:用于服务器签名的公钥,不用保密,但也别改。ClientPub
:用于客户端签名的公钥,不用保密,但也别改。ServerSignedPassword
= HMAC(ServerPub
,SaltedPassword
)ClientSignedPassword
= HMAC(ClientPub
,SaltedPassword
)HashedClientSignedPassword
= Hash(ClientSignedPassword
)Auth
=UserIdentify
+ClientNonce
+Salt
+MixNonce
+MixNonce
,直接连接即可,用于构造本次通讯上下文的签名。SignedAuth
= HMAC(Auth
,HashedClientSignedPassword
)ServerProof
= HMAC(ClientSignedPassword
,Auth
),服务器给客户端的身份证明。ClientProof
=ClientSignedPassword
XORSignedAuth
,客户端给服务器的身份证明。
工作流程
Client-Step1
客户端发送UserIdentify
、ClientNonce
给服务器端。
Server-Step1
- 服务器根据
UserIdentify
读取HashPasswordClient
、PasswordServer
、Salt
、Iteration
。 - 生成
ServerNonce
、MixNonce
。 - 将
Salt
、Iteration
、MixNonce
返回给客户端。
Client-Step2
- 客户端根据前文公式生成
Salt
,Iteration
及Passowrd
计算出SaltedPassword
。 - 算出
Auth
=UserIdentify
+ClientNonce
+Salt
+MixNonce
+MixNonce
。 - 算出
SignedAuth
= HMAC(Auth
,HashedClientSignedPassword
)。 - 算出
ClientProof
=ClientSignedPassword
XORSignedAuth
。 - 将
MixNonce
和ClientProof
返回给服务器。
Server-Step2
- 算出
Auth
=UserIdentify
+ClientNonce
+Salt
+MixNonce
+MixNonce
;注意第一个MixNonce
应使用Server-Step1
发出的,第二个MixNonce
应使用Client-Step2
发来的。 - 算出
SignedAuth
= HMAC(Auth
,HashedClientSignedPassword
)。 - 根据异或运算算出客户端的
ClientSignedPassword
=ClientProof
XORSignedAuth
。 - 算出
HashedClientSignedPassword
= Hash(ClientSignedPassword
)。 - 比对上一步算出的
HashedClientSignedPassword
与数据库存储的HashedClientSignedPassword
是否一致,如果一致则说明密码校验成功。 - 算出
ServerProof
= HMAC(ServerSignedPassword
,Auth
)。 - 将
ServerProof
发给客户端。
Client-Step3
- 算出
ServerSignedPassword
= HMAC(ServerPub
,SaltedPassword
)。 - 算出
ServerProof
= HMAC(ServerSignedPassword
,Auth
)。 - 将
ServerProof
与服务器发来的ServerProof
进行比较,如果一致则说明校验成功。