2

我想创建一个身份验证机制,其中客户端是 JavaScript,它从客户端获取密码和用户名并将其发布到 CGI Perl 脚本。

问题是用户名和密码是自由文本。我想让它加密或散列,但在 CGI 我想检查它,所以我需要再次输入密码。

有任何想法吗?

4

3 回答 3

6

您可能需要考虑使用 https 连接。这解决了您必须自己加密/解密数据的问题(但需要一些努力来设置)。

于 2013-06-19T11:09:37.097 回答
3

这是对建议客户端加密而不是 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)来验证用户身份。您永远不会看到秘密,而只会从身份提供者那里得到是/否消息。

于 2013-06-19T12:13:38.570 回答
2

也许这就是您正在寻找的:crypto-js 所以您可以加密您的数据客户端并在服务器端进行身份验证。

于 2013-06-19T11:03:27.390 回答