简介

SCRAM是一套包含服务器和客户端双向确认的用户认证体系,配合信道加密可以比较好的抵御中间人、拖库、伪造等攻击。 SCRAM是密码学中的一种认证机制,全称Salted Challenge Response Authentication Mechanism(加盐挑战响应验证机制)。它适用于使用基于“用户名:密码”这种简单认证模型的连接协议。SCRAM是一个抽象的机制,在其设计中需要用到一个哈希函数,这个哈希函数是客户端和服务端协商好的,包含在具体的机制名称中。比如SCRAM-SHA1,使用SHA1作为其哈希函数。

SCRAM是一套包含服务器和客户端双向确认的用户认证体系,配合信道加密可以比较好的抵御中间人、拖库、伪造等攻击。

相关字段

定义:

  • Hash(content)指安全Hash函数,如SHA256。
  • HMAC()指使用Hash(content)作为基础实现的HMAC函数,如HMAC(SHA256,Key,Content)
  • UserIdentify:仅用于登录签名的用户身份标识字符串,每次登录时可根据业务任意选用用户名、手机号、邮箱、三方ID等,下次登录可以选另一种,仅作为本次通讯的标识之一使用。
  • Password = Hash(明文密码)
  • Salt:随机生成的盐。
  • Iteration:加盐计算时的迭代次数。
  • SaltedPassword = pbkdf2(PasswordSaltIteration),已加盐的密码。
  • ClientNonce:客户端在Step1时随机生成的字符串,用于对本次交互签名。
  • ServerNonce:服务器在Step1时随机生成的字符串,用于对本次交互签名。
  • MixNonce = ClientNonce | ServerNonceClientNonceServerNonce的_按位或_结果。
  • ServerPub:用于服务器签名的公钥,不用保密,但也别改。
  • ClientPub:用于客户端签名的公钥,不用保密,但也别改。
  • ServerSignedPassword = HMAC(ServerPubSaltedPassword)
  • ClientSignedPassword = HMAC(ClientPubSaltedPassword)
  • HashedClientSignedPassword = Hash(ClientSignedPassword)
  • Auth = UserIdentify + ClientNonce + Salt + MixNonce + MixNonce,直接连接即可,用于构造本次通讯上下文的签名。
  • SignedAuth = HMAC(AuthHashedClientSignedPassword)
  • ServerProof = HMAC(ClientSignedPasswordAuth),服务器给客户端的_身份证明_。
  • ClientProof = ClientSignedPassword XOR SignedAuth,客户端给服务器的_身份证明_。

工作流程

Client-Step1

客户端发送UserIdentifyClientNonce给服务器端。

Server-Step1

  1. 服务器根据UserIdentify读取HashPasswordClientPasswordServerSaltIteration
  2. 生成ServerNonceMixNonce
  3. SaltIterationMixNonce返回给客户端。

Client-Step2

  1. 客户端根据前文公式生成SaltIterationPassowrd计算出SaltedPassword
  2. 算出Auth = UserIdentify + ClientNonce + Salt + MixNonce + MixNonce
  3. 算出SignedAuth = HMAC(AuthHashedClientSignedPassword)。
  4. 算出ClientProof = ClientSignedPassword XOR SignedAuth
  5. MixNonceClientProof返回给服务器。

Server-Step2

  1. 算出Auth = UserIdentify + ClientNonce + Salt + MixNonce + MixNonce;注意第一个MixNonce应使用Server-Step1发出的,第二个MixNonce应使用Client-Step2发来的。
  2. 算出SignedAuth = HMAC(AuthHashedClientSignedPassword)。
  3. 根据异或运算算出_客户端_的ClientSignedPassword = ClientProof XOR SignedAuth
  4. 算出HashedClientSignedPassword = Hash(ClientSignedPassword)。
  5. 比对上一步算出的HashedClientSignedPassword与_数据库存储_的HashedClientSignedPassword是否一致,如果一致则说明密码_校验成功_。
  6. 算出ServerProof = HMAC(ServerSignedPasswordAuth)。
  7. ServerProof发给客户端。

Client-Step3

  1. 算出ServerSignedPassword = HMAC(ServerPubSaltedPassword)。
  2. 算出ServerProof = HMAC(ServerSignedPasswordAuth)。
  3. ServerProof与_服务器_发来的ServerProof进行比较,如果一致则说明_校验成功_。