Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 从用户安全生成的加密密钥';谁的密码?_Django_Security_Encryption_Hash_Cryptography - Fatal编程技术网

Django 从用户安全生成的加密密钥';谁的密码?

Django 从用户安全生成的加密密钥';谁的密码?,django,security,encryption,hash,cryptography,Django,Security,Encryption,Hash,Cryptography,我正在用MySQL建立一个Django网站。我已经决定使用Django内置的pbkdf2-sha256和随机生成的salt散列来存储用户密码 但是,该网站还需要存储许多其他网站(不使用oauth)的第三方登录凭据。所以我研究了AES-256加密,当然问题是在哪里安全地存储加密密钥 现在我的解决方案是:让每个加密密钥=用户实际密码和随机生成的salt的散列(不同于已用于密码存储散列的salt)。salt将存储在表中,实际密码和它的散列显然不是。因此,加密密钥将在登录时生成并临时存储,但在注销时过期

我正在用MySQL建立一个Django网站。我已经决定使用Django内置的pbkdf2-sha256和随机生成的salt散列来存储用户密码

但是,该网站还需要存储许多其他网站(不使用oauth)的第三方登录凭据。所以我研究了AES-256加密,当然问题是在哪里安全地存储加密密钥

现在我的解决方案是:让每个加密密钥=用户实际密码和随机生成的salt的散列(不同于已用于密码存储散列的salt)。salt将存储在表中,实际密码和它的散列显然不是。因此,加密密钥将在登录时生成并临时存储,但在注销时过期。此外,如果不破解原始pbkdf2-sha256散列,破坏服务器的人就无法生成加密密钥,即使这样,它也只能用于该用户,而不是通用密钥

缺点是,如果他们更改/重置密码,他们将不得不重新输入每个站点的凭据。但这并不是什么大问题,而且似乎比将密钥存储在服务器上的某个位置或其他服务器上要安全得多


但我24小时前才知道什么是杂烩,所以我知道什么。我是否忽略了什么,或者这是否合理安全?或者有更好的方法吗?

您提到的算法
PBKDF2
实际上就是为了这个明确的目的而设计的

因此,工作流程将是生成随机盐。然后为用户将其存储在数据库中

使用具有高迭代计数和salt的PBKDF2,生成640位的关键材料(80字节)

前128位成为密码的IV

接下来的256位成为密码密钥(用于AES-256的密钥)

最后256位成为MAC密钥(用于验证加密的密钥)

然后,使用这些密钥(伪代码)加密数据:

现在,解密时,只需反向走回去

key = PBKDF2-SHA256(password, salt, 50000, 80)
iv = key[0:128]
cipherKey = key[128:384]
macKey = key[384:640]

authtext = result[0:32]
ciphertext = result[32:]

if !timingSafeComparison(authtext, SHA256-HMAC(ciphertext, macKey)):
    return false

return AES-256-CBC-DECRYPT(ciphertext, cipherKey, iv)

是的,如果您的用户忘记了密码,则所有加密数据都将丢失。但这就是你想要的,对吗?

这就是:基于密码的密钥派生函数。我意识到了这一点。这就是为什么我用它来创建一个单向密钥,而不是用户密码。我建议再次使用不同的salt密码,将其用作不同登录凭据的单独加密密钥。这样,攻击者就无法访问加密密钥您可以生成高熵salt,并使用salt+密码上的PBKDF来获取密钥+IV以加密数据并存储salt和加密数据,这是长期存储。需要时,您可以使用存储的salt和密码(从何处检索?)访问加密数据。但是你没有密码。您只在用户信息中存储单向散列。而且登录表单帖子早就不存在了。除非您每次需要时都向用户索要pwd,否则您需要将其存储在某个地方,这是您真正的问题,您将pwd存储在何处?这种方法的问题是,当您从中提取的尺寸超过自然尺寸时,PBKDF2的成本会增加。攻击者可能只对输出的一部分感兴趣,因为这足以进行确认,使其能够比合法的哈希程序更快地搜索密码。我更喜欢从PBKDF2输出自然大小,然后使用HKDF生成单个密钥。
ciphertext = AES-256-CBC(data, cipherKey, iv)
authtext = SHA256-HMAC(ciphertext, macKey)
result = '{}{}'.format(authtext, ciphertext)
key = PBKDF2-SHA256(password, salt, 50000, 80)
iv = key[0:128]
cipherKey = key[128:384]
macKey = key[384:640]

authtext = result[0:32]
ciphertext = result[32:]

if !timingSafeComparison(authtext, SHA256-HMAC(ciphertext, macKey)):
    return false

return AES-256-CBC-DECRYPT(ciphertext, cipherKey, iv)