Python中的安全认证系统?
我正在用Python制作一个网页应用,想要有一个安全的登录系统。
我之前做过很多次登录系统,用户登录后会生成一个随机字符串,这个字符串会保存在用户的cookie里,同时也会存储在数据库中。这个方法虽然能用,但安全性不高。
我大概明白一个高级系统的基本原则,但具体细节还不太清楚:
- 登录页面和重要页面要使用HTTPS,这样数据传输更安全。
- 把用户的密码在数据库中保存时要进行加密(比如用bcrypt或sha256?还要加盐吗?)
- 使用一次性令牌(nonce),可以用页面的URL和IP地址来加密。
除了这些,我对如何可靠地检查登录的用户是否真的是这个人,或者如何在多个页面请求和打开的页面之间安全地保持会话等问题一无所知。
能给我一些具体的建议吗?因为我对这种高级安全编程还是个新手。
我只是想实现一个基本的用户登录和登出功能,确保安全,没想要太复杂的东西。
2 个回答
在不知道你具体情况的前提下,很难给出详细的建议。不过,有一点你绝对不要做,那就是重新发明轮子。安全问题很复杂,如果你的“轮子”缺少了什么,你可能直到出问题的时候才会发现。
我不会感到惊讶,如果你的网页框架里已经有处理用户、登录和会话的模块、库或者插件。去看看它的文档并使用它:希望这些东西是由懂一点安全知识的人写的。
如果你想知道它是怎么实现的,可以研究一下这个模块的文档和源代码。
这个回答主要讲的是密码加密,而不是你其他的问题。对于那些问题,我的主要建议是不要自己发明轮子:使用现有的框架,这些框架和谷歌应用引擎(GAE)配合得很好。GAE自带了Django的部署,但也有WebOb的内置安装,所以各种基于WebOb的框架(比如Pyramid、Turbogears等)也可以考虑。这些框架都有现成的库,可以帮你处理很多事情(例如,很多WebOb框架使用Beaker来处理基于cookie的会话)。
关于密码加密……因为你在其他评论中提到你在使用谷歌应用引擎,所以你应该使用SHA512-Crypt来加密密码。
另外一些主要的选择,用来尽可能安全地存储密码加密值的有BCrypt、PBKDF2和SCrypt。不过,GAE并不支持这些算法的C加速,所以你只能通过纯Python的实现来使用它们。可惜的是,这些算法在纯Python实现中处理的位数太多,速度不够快,无法做到既安全又响应迅速。而GAE的Python crypt
模块提供了C加速的SHA512-Crypt支持(至少我每次测试都是这样),所以它的运行强度是足够的。
在写实际代码方面,你可以直接使用crypt
模块。你需要在传入crypt时自己生成盐字符串,并在加密新密码时调用crypt.crypt(passwd, "$6$" + salt)
。$6$
表示使用SHA512-Crypt。
另外,你也可以使用Passlib库来帮你处理大部分事情(免责声明:我是这个库的作者)。如果你想快速在GAE上部署:
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["sha512_crypt"],
default="sha512_crypt",
sha512_crypt__default_rounds=45000)
# encrypt password
hash = pwd_context.encrypt("toomanysecrets")
# verify password
ok = pwd_context.verify("wrongpass", hash)
注意:如果你关心密码安全,无论你做什么,不要使用单一的HASH(salt+password)算法(例如Django、PHPass等),因为这些算法很容易被暴力破解。