鉴于通过 HTTP 进行的通信
- 使用 SSL 加密
- 使用公钥固定来防止中间人攻击
通过在基本访问身份验证上使用加盐挑战响应身份验证机制(SCRAM) 并随后为每个请求使用令牌,是否以任何方式提高了安全性?
鉴于通过 HTTP 进行的通信
通过在基本访问身份验证上使用加盐挑战响应身份验证机制(SCRAM) 并随后为每个请求使用令牌,是否以任何方式提高了安全性?
tl; dr:我一般不会推荐它,但它在特定情况下可能有用
HMAC(PBKDF2(password), "Client Key") XOR HMAC(H(HMAC(PBKDF2(password), "Client Key")), AuthMessage)
(说真的,我不是在编造这个!)HMAC(HMAC(PBKDF2(password), "Server Key"), AuthMessage)
第一点是不幸的,但第二点才是真正的杀手锏。现在智能手机和平板电脑无处不在,您根本无法假设客户端能够通过足够的迭代快速计算 PBKDF2 以确保安全。
我看到 SCRAM 的用途是客户端受信任但服务器不信任。这对于 Web 应用程序永远不会正确(因为“客户端”是由...服务器发送的 JavaScript),并且有时对于本地应用程序是正确的。我能想到的最好的例子是Wikipedia 给出的例子:SMTP、IMAP 和 XMPP,在这些例子中,您信任您的电子邮件或聊天客户端,但正在向潜在的恶意第三方服务器进行身份验证。
如果客户端强制使用高迭代次数和唯一盐,它可能会降低 DNS 劫持与流氓 CA 结合的风险,但您已经通过证书固定做到了这一点。唯一需要防御的是您的服务器是恶意的,这在某些情况下可能很有用,但前提是收益超过 SCRAM 的劣势。
如果您知道将使用强密码,SCRAM可能有助于防止服务器获取密码,但该密码也将在其他地方重复使用(如果不重复使用,您为什么要关心服务器是否知道它?) . 不幸的是,这并不能真正强制执行,理想的情况是无论如何都要使用唯一的密码。
在 SCRAM 中,服务器存储:
ServerKey = HMAC(PBKDF2(password), "Server Key")
(其中"Server Key"
是已知的恒定 HMAC 密钥)*StoredKey = H(HMAC(PBKDF2(password), "Client Key"))
(同上"Client Key"
)要进行身份验证:
ClientKey = HMAC(PBKDF2(password), "Client Key")
StoredKey = H(ClientKey)
ClientSignature = HMAC(StoredKey, AuthMessage)
(AuthMessage
所有先前交换的消息和随机数的连接在哪里,用逗号分隔)ClientProof = ClientKey XOR ClientSignature
ClientProof
服务器ClientSignature = HMAC(StoredKey, AuthMessage)
ClientKey = ClientProof XOR ClientSignature
ServerSignature = HMAC(ServerKey, AuthMessage)
H(ClientKey) == StoredKey
,证明客户端知道密码(或至少ClientKey
)ServerSignature
ServerSignature
并将其与服务器返回的值进行比较,验证服务器是否知道ServerKey
这是相当简化的,因为它排除了一些东西,如哈希选择、编码、消息格式和通道绑定,但它应该很好地了解它是如何工作的。
* PBKDF2 的所有用途显然也包括盐和迭代计数,SCRAM 设置dkLen
为所选哈希的输出长度
RFC指出以下优点:
o 身份验证数据库中存储的身份验证信息本身不足以模拟客户端。如果数据库被盗,信息会被加盐以防止预先存储的字典攻击。
o 服务器无法将客户端模拟到其他服务器(服务器授权的代理除外)。
o 该机制允许使用服务器授权的代理,而不要求该代理对后端服务器具有超级用户权限。
o 支持相互认证,但只有客户端被命名(即服务器没有名字)。
您的问题仅考虑连接安全性,而 SCRAM 也考虑了客户端凭据的安全性。它最明显的优势是它可以防止服务器操作员获取用户凭据,因为它们以加盐和散列格式传输,而在简单的 TLS 连接上它以明文传输。