2012-11-30 58 views
8

我想使用scrypt为我的用户的密码和salt创建哈希。我发现了tworeferences,但有些事情我不了解它们。如何使用scrypt在Python中为密码和salt生成哈希

他们使用scrypt加密和解密函数。一个加密一个随机字符串,另一个加密盐(这看起来是错误的,因为只有密码而不是盐被用于解密)。它看起来像解密函数被用来验证密码/ salt作为解密的副作用。

基于我理解的很少,我想要的是密钥导出函数(KDF)而不是加密/解密,并且KDF可能由scrypt生成并用于加密/解密。实际的KDF在幕后使用,我担心盲目地遵循这些示例会导致错误。如果使用scrypt加密/解密函数来生成和验证密码,我不理解被加密的字符串的作用。其内容或长度是否重要?

回答

9

你是对的 - 这两个链接正在使用的scrypt函数是scrypt文件加密工具,而不是基础kdf。我一直在努力为python创建一个独立的基于scrypt的密码哈希,并且自己也遇到了这个问题。

scrypt文件实用程序执行以下操作:选择特定于系统的scrypt的n/r/p参数&“min time”参数。然后它生成一个32字节的盐,然后调用scrypt(n,r,p,salt,pwd)来创建一个64字节的密钥。该工具返回的二进制字符串由以下内容组成:1)包含n,r,p值和用二进制编码的盐的头; 2)头部的sha256校验和;和3)使用密钥的前32个字节的校验和的hmac-sha256签名副本。接下来,它使用密钥的其余32个字节来对输入数据进行AES加密。

有一对夫妇的这种影响,我可以看到的:

  1. 输入的数据是没有意义的,因为它实际上并不影响盐被使用,以及加密()产生新的盐每一次。

  2. 您不能手动配置n,r,p工作负载,也不能以其他任何方式配置难以理解的最小时间参数。这并不是不安全的,但是控制工作因素是一种相当尴尬的方式。解密通话再生的关键,并确定它的HMAC

  3. 之后,它会拒绝一切在那里,如果你的密码是错误的 - 但如果它是正确的,它会继续解密数据包。这是攻击者无需执行的大量额外工作 - 它们甚至不需要派生64个字节,只需要32个字节来检查签名。这个问题并不是完全不确定,但做你的攻击者的工作并不是永远不可取的。

  4. 有没有办法配置salt key,派生的密钥大小等等,当前值并没有那么差,但仍然不理想。

  5. 解密实用程序的“最大时间”限制对于密码散列是错误的 - 每次调用解密时,它都会估计您的系统速度,并在最大时间内做出一些“猜测”,以确定它是否可以计算密钥 - 是更多您的攻击者不必做的开销(请参阅#3),但这也意味着解密可能会在系统负载过重时开始拒绝密码。

  6. 我不知道为什么科林珀西瓦尔没有使公共API的KDF &参数选择代码的一部分,但它INFACT明确标记为“私人”的源代码里 - 甚至没有出口的连接。这使我犹豫不决,无需进行更多的研究就直接访问它。

总而言之,我们需要的是能够scrypt存储一个不错的哈希格式,并露出下面的KDF和参数选择算法的实现。我目前正在为passlib自己做这个工作,但它并没有看到太多的关注:(

只是为了底线的事情 - 虽然这些网站的说明是'好',我只是使用一个空字符串作为该文件的内容,并意识到的额外开销和问题

+0

谢谢。我对一些解密进行了计时,即使对于一个字符串,它们看起来也是高度可变和耗时的。我可以忍受的其他问题,但不知道要放置什么值,以便解密不会返回“解密文件将需要太长的时间 ”的错误使它对我无法使用。 bcrypt看起来更友好,对我来说可能会很好。 – Mitch

4

这两项引用了它完全错误不要encryptdecrypt渣土:。只使用hash

的KDF不直接暴露但hash足够接近。(事实上,在我看来是更好,因为它混合一个PBKDF2三明治的馅。)

This example code作品既python2.7和python3.2。它采用PyCrypto,passlib和PY-scrypt,但只需要 PY-scrypt。

您将需要使用持续时间比较功能,如passlib.utils.consteq来减轻计时攻击。

您还需要仔细选择的参数。默认值logN = 14,r = 8,p = 1表示使用16 MiB内存1“round”。在一台服务器上,你可能想要更像10,8,8的内存 - 更少的内存,更多的CPU。你应该在你的硬件下你的预期的负载。

相关问题