我想创建一个身份验证机制,其中客户端是 JavaScript,它从客户端获取密码和用户名并将其发布到 CGI Perl 脚本。
问题是用户名和密码是自由文本。我想让它加密或散列,但在 CGI 我想检查它,所以我需要再次输入密码。
有任何想法吗?
我想创建一个身份验证机制,其中客户端是 JavaScript,它从客户端获取密码和用户名并将其发布到 CGI Perl 脚本。
问题是用户名和密码是自由文本。我想让它加密或散列,但在 CGI 我想检查它,所以我需要再次输入密码。
有任何想法吗?
您可能需要考虑使用 https 连接。这解决了您必须自己加密/解密数据的问题(但需要一些努力来设置)。
这是对建议客户端加密而不是 HTTPS 的评论的回应。
重要的是要考虑您要保护什么免受谁的侵害。
如果数据库受到损害,服务器端哈希对于争取时间很重要。
从服务器/CGI 脚本的角度来看,您会收到某种形式的身份验证令牌,您希望对其进行验证。
如果其他人可以访问明文数据库,则将令牌与存储的明文进行比较是危险的。如果其他人可以物理访问服务器、访问备份或可以在服务器上运行软件,这是不安全的。即便如此,错误的配置或未知的漏洞也可能暴露明文密码。
因此,某种(不可逆的)散列必须发生在服务器端。MD5 不是一个可行的解决方案。实际上,没有“快速”散列(包括 SHA 算法)再提供良好的保护:它们被优化用于快速和安全的完整性验证,而不是使密码破解尽可能困难。这可以通过重复散列/密钥拉伸来缓解(参见WP 文章)。包括随机“盐”也很重要。不要在这里考虑“优化”。
运输加密可防止窥探者。
秘密访问令牌必须从客户端安全地传输到服务器。这通常通过 HTTPS 完成。
如果密码在客户端被散列,散列的访问令牌有效地成为必须保护的秘密。可视化:
CLIENT | TRANSPORT | SERVER
| |
password => HaShEd | >>>>>>>>>> | verification that “HaShEd” is valid.
^ | never sees “password”.
snooper can see “HaShEd” | |
can make malicious request |>>|
这与未加密的密码没有什么不同。因此,任何预先散列的访问令牌都必须在传输期间加密,例如通过 HTTPS。如果您对密码使用可逆加密,则必须安全地传输加密密钥。这是非对称加密的一个已解决问题,但如果您只使用 HTTPS,您不必考虑所有这些,它会自动发生。
仅当您想要保护服务器的机密时,在客户端进行加密才是明智的。一个用例是将机密文件上传到服务器。如果它们在客户端加密,则服务器可能会受到损害,而文件不会受到损害。对于身份验证,这不提供任何有用的功能。
它所能做的就是让用户产生一种虚假的安全感。实际的秘密只是与用户知道的访问令牌不同。
除了密码之外,还可以使用无密码身份验证方案。其中最重要的是 OpenID(与 stackoverflow 一起使用),您可以信任第三方身份提供商(例如 Google、Facebook、GitHub)来验证用户身份。您永远不会看到秘密,而只会从身份提供者那里得到是/否消息。
也许这就是您正在寻找的:crypto-js 所以您可以加密您的数据客户端并在服务器端进行身份验证。