如何管理密码哈希?

时间:2014-05-24 20:47:57

标签: java hash network-programming passwords

我正在制作一个带有客户端 - 服务器架构的多人游戏,我想知道为记录部分散列密码的确切过程是什么。玩家第一次登录时,是否应该通过网络发送密码,然后让服务器对其进行哈希处理(并存储哈希值)?如果是这样,哈希的现代推荐是什么(MD5,SHA等),我该如何用Java实现呢?

1 个答案:

答案 0 :(得分:0)

哈希只是一种单向的,不可逆的,确定性的转变。这意味着给定一个输入字符串(在本例中为密码),可以轻松地计算散列,并且反复散列相同的输入字符串将提供相同的散列,即使在不同的机器上也是如此,只要相同的规则是使用

由于“雪崩效应”,散列甚至微小不同的字符串会产生大不相同的散列。您无法从哈希中预测密码,也无法选择与哈希匹配的密码,除非是MD5等破碎的算法。

不应使用MD5和SHA1。

替代方案包括SHA256,SHA384和SHA512等标准,像Whirlpool这样的古怪标准,以及PBKDF2等多级标准。 SHA作为哈希计算起来相当容易(计算哈希的速度越慢,bruteforce的速度就越慢)。 PBKDF要慢得多(如果我没有记错的话,大约可能是1000次哈希/秒),但对于暴力来说同样慢。

如果密码被传输,如果正在使用流氓服务器或网络嗅探器,则不安全。我建议对密码进行哈希处理,通过网络发送密码,然后在服务器端再次对其进行哈希处理,最好是每台服务器使用一次盐。如果初始哈希是使用与密码连接的用户名计算的,那么对安全性来说同样不错。

因此,如果H(X)是X的散列,将发生以下情况:

  1. 登录时,客户端计算H(用户名+密码)
  2. 客户端通过网络发送用户名和此哈希值。即使知道用户名,也没有获取密码的安全风险;它仍然必须是强制的,并且用户名使用名为 rainbow table 的数据库排除了一种攻击
  3. 服务器哈希使用salt发送的哈希值,如果用户是新用户,则将其存储到登录数据库,如果不是新用户,则将其与现有条目进行比较。 (也就是说,它存储H(salt + H(用户名+密码))。H(用户名+密码)当然是由客户端提供的。每个服务器的salt应该是不同的,但是在给定的服务器上不能更改。这可以是管​​理员设置的服务器配置文件中的设置。