2012-04-05 201 views
9

我正在使用MD5(无盐)散列用户密码的系统上工作。我想使用SHA-512和盐更安全地存储密码。使用SHA-512和salt来散列MD5散列密码?

虽然这很容易实现未来的密码,但我还想改造现有的MD5哈希密码,最好不要强迫所有用户更改其密码。我的想法是只使用SHA-512和适当的盐来散列现有的MD5散列。然后,我可以在数据库中设置一些标志,指明哪些密码是从纯文本进行散列的,哪些是从MD5哈希散列的。或者我可以在验证用户时尝试这两种方法。甚至可以用MD5和SHA-512/salt对新密码进行哈希处理,这样就可以将它们视为旧密码。

以编程方式,我不认为这会是一个问题,但我不太了解加密/散列,以便知道我是否以任何方式危害散列的质量,方法是应用SHA-512/salt散列到已经被MD5散列的密码。我的第一个直觉是,如果有的话,它会更强大,一个非常轻松的关键。我的第二个直觉是我并不真正知道自己在说什么,所以我最好得到建议。有什么想法吗?

+0

与MD5相比,SHA-512只能提供很小的改进(例如:'MD5(salt + password)'实际上等同于'SHA512(salt + password)')。 MD5和SHA系列之类的通用散列函数不是用来存储密码的。使用bcrypt。 – NullUserException 2012-10-30 21:55:53

+0

非常真实。我其实打算做关键的延伸,但没有在我的问题中说清楚。我最终使用PBKDF2而不是天真地实现我自己的密钥伸展算法。 – 2012-10-31 13:00:14

回答

6

带有密码原语的函数组合是危险的,如果可以避免的话不应该这样做。针对您的问题类型的常见解决方案是在迁移期间保留两个哈希值,尽可能使用新的哈希值并透明地升级旧密码(当您检查密码并匹配时,使用新算法重新哈希并存储它)

如果你有一个基于挑战 - 响应的方案,你不能看到明文密码,但由于你看起来有一个不会改变的存储盐,我假设你的应用程序做了散列。

+0

这是一个很好的答案。我之前正在实施这种类型的解决方案,这是一个很好的方法。 – jeffsix 2012-04-05 16:50:05

+0

感谢您在用户登录时进行透明刷新的建议!您是否有任何链接可以解释为什么将SHA-512散列应用于MD5散列值比将SHA-512散列应用于纯文本密码更安全?我很想知道为什么... – 2012-04-05 17:36:07

+1

@JeremiahOrr:对于您的具体应用,正确使用足够长的不可预知的盐将在安全性方面比改变哈希方案做得更多。正如j13r所解释的那样,在MD5上应用SHA不会扩大可能哈希的空间,因为它们受到MD5的可能结果的限制。另外,使用专门针对密码进行优化的单向函数会更好,例如[PBKDF2](http://en.wikipedia.org/wiki/PBKDF2)。 – mensi 2012-04-06 22:49:05

1

相信你的第二本能。使用专门用于散列密码的现有库,而不是尝试自己制作密码。

大概用MD5来散列你的新密码,然后用你的密码哈希库对MD5进行散列。这样,您可以保持与旧密码的向后兼容性。

I.e. password_hash(所有旧的,md5'd密码)和password_hash(MD5(新口令))

(警告:我不是一个加密专家)

http://www.codinghorror.com/blog/2007/09/youre-probably-storing-passwords-incorrectly.html

+0

呵呵,我不打算制作我自己的哈希库,我只需要知道如何处理现有的MD5哈希密码! – 2012-04-05 12:15:25

+0

我不是密码学专家,但我只是在现有的MD5密码上运行密码散列函数。对于新密码,您首先要执行旧的MD5算法,然后将其提供给适当的密码散列函数。 这个,或者你可以以某种方式标记密码是否在数据库中使用旧的或新的算法(或者无论你是否存储它)。 – tangrs 2012-04-05 12:18:29

+0

@tangrs他原来的密码也是MD5哈希值,它已经被保护。他想用更安全的盐切换到SHA-512。为什么你会建议他双重哈希?这仍然不能解决如何区分新旧密码的问题。而双重散列是通过默默无闻的安全性,这与安全性一样好,因为没有人知道该怎么做以及如何维护它。 – Churk 2012-04-05 12:21:07

4

如果用MD5哈希第一,你只会有MD5(128位)的传播。 SHA512的大部分空间不会被您的密码覆盖。所以你没有利用SHA512,但它不会比MD5差。

如果有人获得SHA512散列并且不知道盐(这个你必须以某种方式执行),你将无法查找散列并获得密码 - 这是可能的您现在拥有的MD5数据库。

所以是的,你可以重新刷新现有的MD5密码。但正如第一段所述,将MD5应用于所有新密码并将它们散列为SH512将是一个不好的主意。一个简单的实现是在散列旁边的数据库中有一个布尔型的'salted'字段(但不要把salt放在那里)。

+0

'但是不要把盐放在那里 - 盐的全部要点是它不必保密,只需将明文放在哈希值旁边(每个密码都有独特的散列!)。另外:基于任何实际的事实或仅仅是一些直觉,是否“用SHA-512散列MD5密码不会造成任何伤害”?因为通常顺序地应用多个散列会造成更多的伤害。 – Voo 2012-04-05 12:28:53

+0

散列函数的要点是它提供了可变长度字符串和n位数之间的唯一映射。任何好的散列函数都可以避免冲突,事实上,在SHA-512甚至MD5上产生冲突是非常困难的(除非你有任意的长度,而不是在密码中)。将128位值映射到512位空间是微不足道的(您有2 ^(512-128)个未使用的值)。碰撞(这是伤害)极不可能发生(概率2 ^(128-512))。 – j13r 2012-04-05 12:37:27

0

如果你看看大多数银行和高安全性的人有密码更改。他们中的大多数基本上会询问使用旧加密方法的人创建新密码。我认为你首先要为所有现有的旧MD5密码用户设置一个标志,并通知他们需要创建新密码并慢慢迁移到新系统。这样,当你遇到任何问题时系统出现故障时,你不会问这是一个新用户还是旧用户。我们是双重哈希还是单一?不应该比较两个散列作为可能的答案,因为如果MD5('abc')=> 123,SHA('NO')=> 123,那意味着某人可能输入了错误的密码但仍然进入。