如何解决DJANGO 中的 Argon2 和会话变量中的密码
到目前为止,我使用 SHA256 来散列密码(我知道,很糟糕),现在我想切换到 Argon2。
我的问题是,如果我理解正确,我现在必须将纯文本密码存储在会话变量中。
现在我将 SHA256 哈希值存储在会话变量中,并且我有一个 check_user
函数来检查用户是否仍然登录使用我的大多数函数。
def check_user(request):
if 'email' not in request.session or not request.session['email']:
return False
if 'pw_hash' not in request.session or not request.session['pw_hash']:
return False
try:
Clients.objects.get(pk=request.session['email'])
except Clients.DoesNotExist:
return False
if request.session['pw_hash'] != Clients.objects.get(pk=request.session['email']).password:
return False
return True
如果我切换到 Argon2,据我所知,我必须将普通密码存储在会话变量中才能使用 PasswordHasher().verify
,这在 IMO 是一种不好的做法。
解决方法
由于对默认身份验证系统缺乏了解,您已经推出了自己的系统并使用不同的 API 实现了几乎相同的内容。
Django 在使用 login 函数时做了什么(为简洁起见进行了简化):
- 在会话中存储用户 ID
- 在会话中存储用于身份验证的后端
- 使用盐存储哈希密码的 SHA-256 哈希值(以确保源字符串至少为 256/8 = 32 字节长)
最后一点类似于您的 check_user
方法,只是它更安全一点:它不会将密码哈希公开给会话存储,因此真正的密码哈希只在一个地方。
然后中间件调用 get_user 来验证这个哈希值。
它比较使用更快的方法(sha-256)只是为了排除会话属于另一个用户或密码已在不同浏览器中更改:如果您在桌面上更改密码,您的手机手机将在下次尝试使用其会话时注销(前提是它们不共享 cookie)。
这个更简单的比较并不会降低它的安全性,因为为了猜测密码,你仍然需要破解真正的哈希值(在你的情况下是 Argon-2),而你甚至没有那个哈希值如果您获得了会话存储的访问权限。
总而言之,我强烈建议彻底阅读 Django 身份验证系统以及如何扩展它,因为它经过了比您自己的系统更多的用户的审查和实战测试。此外,Django 生态系统中更多使用 Django 用户的包将向您开放。
同时,您可以使用与上图相同的机制:
from django.utils.crypt import constant_time_compare
def check_user(request):
if 'email' not in request.session or not request.session['email']:
return False
if 'pw_hash' not in request.session or not request.session['pw_hash']:
return False
try:
user = Clients.objects.get(pk=request.session['email'])
except Clients.DoesNotExist:
return False
return constant_time_compare(session['pw_hash'],user.password)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。