Secure authentication system in python?

前端 未结 2 1570
生来不讨喜
生来不讨喜 2021-02-10 16:31

I am making a web application in python and I would like to have a secure login system.

I have done login systems many times before by having the user login and then a r

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-10 17:08

    This answer mainly addresses password hashing, and not your other subquestions. For those, my main advice would be don't reinvent the wheel: use existing frameworks that work well with GAE. It offers builtin deployments of Django, but also has a builtin install of WebOb, so various WebOb-based frameworks (Pyramid, Turbogears, etc) should also be considered. All of these will have premade libraries to handle a lot of this for you (eg: many of the WebOb frameworks use Beaker for their cookie-based session handling)


    Regarding password hashing... since you indicated in some other comments that you're using Google App Engine, you want to use the SHA512-Crypt password hash.

    The other main choices for storing password hashes as securely as possible are BCrypt, PBKDF2, and SCrypt. However, GAE doesn't offer C-accelerated support for these algorithms, so the only way to deploy them is via a pure-python implementation. Unfortunately, their algorithms do way too much bit-fiddling for a pure-python implementation to do a fast enough job to be both secure and responsive. Whereas GAE's implementation of the Python crypt module offers C-accelerated SHA512-Crypt support (at least, every time I've tested it), so it could be run at sufficient strength.


    As far as writing actual code goes, you can use the crypt module directly. You'll need to take care of generating your own salt strings when passing them into crypt, and when encrypting new passwords, call crypt.crypt(passwd, "$6$" + salt). The $6$ tells it to use SHA512-Crypt.

    Alternately, you can use the Passlib library to handle most of this for you (disclaimer: I'm the author of that library). For quick GAE deployment:

    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)
    

    Note: if care about password security, whatever you do, don't use a single HASH(salt+password) algorithm (eg Django, PHPass, etc), as these can be trivially brute-forced.

提交回复
热议问题