8 ms·
Django-bcrypt
- stevelosh 16y agoStep 1: Install Step 2: Add to INSTALLED_APPS Step 3: Enjoy more secure password hashing. ... Step 4: Set BCRYPT_ROUNDS to something higher than 12 when computers get faster.
- nicksergeant 16y agoYou sir, are a machine. Steve started working on this 3 feet behind me a little less than 2 hours ago.
- jezdez 16y agoIt took him two hours to monkey patch a few methods?
- nicksergeant 16y agoI left a few minutes after he started. He very well might've been banging his head against other (client-related) issues within those two hours.
- stevelosh 16y agoActually the code was already written -- see the bottom of the README. It took about 30-40 minutes to: * Add the BCRYPT_ROUNDS setting. * Remember how to allow for an optional setting (`if foo in settings` and `settings.get(foo, default)` don't work). * Add the setup.py file. * Write a README. * Test with a real Django site to make sure nothing was broken. * Create and push to repos on BitBucket and GitHub.
- TravisLS 16y agoHow handy. Thanks for putting this together and instantly shortening my to-do list.
- makeramen 16y agobitbucket repo: http://bitbucket.org/dwaiter/django-bcrypt http://bitbucket.org/dwaiter/django-bcrypt
- deleted 16y ago[deleted]
- TylerBrock 16y agoHey, I'm new to Django, can someone explain what bcrypt is and why it is important?
- ylem 16y agoWhat were your timings like for bcrypt using 12 rounds? Also, while for the SHA-x algorithms, there have been numerous tests--what about for the pycrypt module?
- stevelosh 16y agoTimings are going to be completely dependent on the server. Anything I tell you will be wrong unless you're running on my server. And I didn't test any SHA-x algorithms. Any algorithm that has a time you can't easily increase by tweaking a number (BCRYPT_ROUNDS) will eventually become insecure as computers get faster.
- JoachimSchipper 16y agoIt's not straight SHA-x, I'd wager; glibc includes a version of phk's MD5-based crypt() based on SHA2 (with some bonus insanity thrown in; it's a spawn of MD5 crypt and Drepper, after all.) Like md5crypt, this new crypt() is not based on established cryptographic principles.
- gst 16y agoBcrypt (or scrypt) should actually be used as default for password hashing in application servers. Using something like crypt/md5/sha-1 hashing per default is just completely irresponsible.
- cdavid 16y agoWhy bcrypt should be used instead of sha-1 ? (I am genuily asking, I don't know anything about security).
- SoftwareMaven 16y agohttp://codahale.com/how-to-safely-store-a-password/ http://codahale.com/how-to-safely-store-a-password/
- Groxx 16y agoEssentially, because it's slow. SHA is designed to be fast, so dictionary attacks can find huge amounts of matches nigh-instantly, and rainbow tables (or GPU EC2 instances!) exist to brute-force up to 8-12 characters, more than enough to crack most people's passwords. You can salt the hash (basically: pre-pend a unique string to the password) to defeat rainbow tables, but SHA doesn't do this by default. You can SHA something more than once to slow things down, but SHA doesn't do this by default (and rainbow tables still work - they're based on repeated hashings). BCrypt is slow by design (ie, thousands of times slower). It's a much-harder calculation, and it automatically uniquely salts what it's hashing, and you can make it more secure incrementally by simply running it through more steps (it's designed to do this). The speed isn't noticeable to a user while logging in because checking if their password is correct is still extremely quick, but attempted-brute-forcers run up against a brick wall as their attempts are now rainbow-table-proof and slower by orders of magnitude. Best of all: it does all this by default, and it stores all the necessary information in the result so comparing values against it is fool-proof. You can't mis-use it. SCrypt takes all the advantages of BCrypt and goes a step further: it guarantees that a certain amount of memory (ie, large) is required to perform the hashing function. So while SHA / BCrypt can still be attacked more quickly by, say, performing a thousand operations at a time through custom hardware, SCrypt can demand so much memory that it's simply infeasible to do so, so you're stuck testing one. password. at. a. time. It's the ultimate death to brute-forcing, basically.
- marcinw 16y agoUnfortunately, for a lot of us working in locked down environments, this code makes use of the py-bcrypt module which uses the bcrypt C implementation. If you're running on GAE, you're out of luck. I keep telling myself to port to pure Python, but haven't had time. Anyone interested?
- amalcon 16y agoThere's a pure-Python implementation of PBKDF2. I know it's not as good as bcrypt or scrypt, but at least it's better than MD5 or one of the SHA's.
- koenigdavidmj 16y agoI saw a Twitter discussion with Colin a couple weeks ago here he pointed out that Python no longer guarantees constant time for all of the basic binary operations like addition (since fixed width integers can spill over to arbitrary precision math if you overflow them, or breathe on them wrong). Be careful.
- amalcon 16y agoOh boy. That could get messy.
- dfox 16y agoPassword hashing function almost by definition does not handle any data that must be protected from the user, so side channel leaks do not make much sense. Only secret information comes into play in final comparison of hash of user supplied password and your stored hash and I don't see any way of exploiting possible timing leak in that comparison that does not require breaking the hash in the first place.
- tptacek 16y agoSide channels don't matter for bcrypt.
- 16y ago
- cavilling_elite 16y agoI thought I remember a post a while back but: What is the cost (time) of using bcrypt instead of the default?
- stevelosh 16y agoPretty much anything you want it to be. The higher the work factor (BCRYPT_ROUNDS in this app), the more time it takes. That's the beauty of bcrypt.
- JoachimSchipper 16y agoThat said, you might want to scale it back a little. 2^12 rounds takes 1-2 CPU seconds (on a different implementation, but still.)
- svlla 16y agonext step is to make this the default. unfortunately the django overlords think it's not important enough to be default.
- jacobian 16y agoA few things: First, There's no such things as "the django overlords". We're an open source community of thousands. Hundreds contribute. Dozens have commit access. Vry few among these contributors, and none (that I know of) on the commit team thinks that bcrypt support "is not important." If you'd like to prove me wrong, please cite your source. Now, this has been proposed a few times (http://code.djangoproject.com/ticket/5787 http://code.djangoproject.com/ticket/5787, http://code.djangoproject.com/ticket/5600 http://code.djangoproject.com/ticket/5600). Each time, substantive problems with the approach have been found. A few choice quotes from the discussion should illustrate the issues: Me, on #5600: "[T]here's a problem with supporting any hash schemes not in Python 2.3 (our lowest supported Python version): it means databases created with a different version of Python break when used under a lower one." (Now it's Python 2.4, and 2.5 soon, but the problem still holds.) Malcolm, on #5787: "As soon as you start generating passwords that are only computable based on an optional model, the database can only be used with Django installations that have that model available. This removes the ability to move the database around easily. Django operates on a "batteries included" philosophy for exactly that reason: runs anywhere without lots of extra dependencies." Worse, this third-party module (i.e. Python bcrypt module), last I checked, failed to build on Windows. As much as I hate supporting Windows, I recognize why we have to. What I'm trying to say is that the issue is technical, not personal or political as you seem to think. If the technical issues can be overcome, I don't see why bcrypt support couldn't be the default. Finally, I'll close with the obligatory note that open source projects get driven forward by people scratching their own itch. If this bothers you, fix it. If your fix is rejected, try again. If you think we're a bunch of asshats, fork the project. Do any of those things, and I'll respect you. Complain and sling personal attacks and I won't.
- stevelosh 16y agoThis is why I chose to make this a separate app instead of embarking on a painful journey to get it into core. Those of us that run OSes that don't suck and don't use versions of Python that are older than the average hamster's lifespan can add two lines to their project and be more secure TODAY.
- kirubakaran 16y agoDoes anyone know how to use bcrypt on App Engine? py-bcrypt is not pure python and hence can't be used.
- pjscott 16y agoI don't know of any pure-Python bcrypt implementation, but App Engine will let you calculate SHA-1 hashes with the built-in hashlib module. To make this slow enough, you'll need to iterate it a bunch of times (at least 1000 is the usual recommendation). Something like this: import hashlib def slow_hash(password, salt, iterations=2000): h = hashlib.sha1() h.update(password) h.update(salt) for x in range(iterations): h.update(h.digest()) return h.digest() I haven't tested this code, but hopefully it illustrates the general idea. Repeatedly run the hash function on the output of the previous iteration. You may need to bump up the number of iterations later as computers get faster. It's not as good as bcrypt, but it also doesn't suck, and it should run just fine on App Engine.
- lamby 16y agoIs it just coincidence that I wrote almost-identical code about 7 hours before this? (https://github.com/playfire/django-bcrypt/ https://github.com/playfire/django-bcrypt/)