WebApp密码管理-哈希、加盐等

6
我正在寻找一种在Web应用程序中实现最安全(但可行的)密码管理方式。
目前,我将密码保存为哈希值。应用程序的DB账户仅限于执行存储过程,并通过向存储过程提供用户名和哈希密码来验证用户,该存储过程返回1(真)或0(假)。
因此,即使您拥有应用程序的DB账户,也无法从服务器获取密码。这就是我喜欢这个解决方案的原因。但是,要使用此解决方案,客户端必须通过Web提交其密码,或者至少提交可以被捕获的静态哈希。
所以我想到了使用以下握手方式:
- 客户端请求服务器的salt。 - 随机salt分配给客户端并存储在服务器上,供单个客户端使用。 - 客户端进行Hash(salt + password),并将此哈希返回给服务器。 - 服务器进行Hash(salt + password),并检查是否与客户端相同。
使用这个握手方式可以在不发送密码本身或其静态哈希的情况下检查密码。只需动态盐值哈希,每次用户登录时都不同=>高度安全。
但是,对于这个握手,我需要从DB获取密码或至少是哈希密码。但这会使某人至少获得哈希密码并在应用程序之外进行暴力破解。
您会选择什么?将密码保留在DB中并在其中进行任何操作(安全服务器),还是将其从DB中取出并在外部进行操作(安全传输)?
提前感谢, 马克斯
1个回答

3
您提出的解决方案并不能真正解决问题。服务器必须知道密码,因此它必须在某个时候以明文传输,这正是您最初想要避免的。这样,您只能避免每次发送密码,但如果有人在第一次传输时抓住了它呢?
我认为您不应该重复造轮子 :-) 对所有连接使用SSL,然后您的第一个解决方案就可以正常工作了。您甚至可以在客户端执行哈希处理,因此只有哈希值通过安全通道发送。您的服务器将永远不会知道密码,也不需要知道。

1
同意,SSL 应该足够安全。在数据库中一定要对密码进行哈希处理,虽然现在 MD5 算法不太可靠,所以我可以使用更加安全的哈希算法来执行此操作。你提出的握手方式类似于 MS-CHAP,但这种方法也是有问题的。 - Jamie Chapman
你说得没错,但我认为密码被嗅探的可能性在这一次中不高,比起用户后面登录的几百或几千次。我的连接仍然是SSL加密的,我只是想要额外的安全保障。目前我使用FormsAuthentications内置的SHA1哈希算法,但是在另一个地方我需要SHA-256,所以我打算转换过去。你认为存储过程GetUser应该返回哈希密码吗?还是只是返回null呢? - Marks
1
当你谈论“安全性”时,你总是假定最坏的情况。你假定攻击者总是存在并以最大效果利用您系统中的每一个弱点。在这个意义上,无论他能读取您的密码一次还是一百次,事实上他都可以读取它。你的客户不想听到你说“攻击者可能不太可能读取你的密码” :-) 无论您的存储过程返回哈希值还是null,都取决于您,服务器应该采用其他手段进行保护,以防止远程访问(如防火墙、安全补丁等)。 - David Sauter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接