Opened 19 years ago
Closed 18 years ago
#4151 closed (duplicate)
Patch to add support for more secure password hashes in Python 2.5 or newer
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Contrib apps | Version: | dev |
| Severity: | Keywords: | authentication, password, hash | |
| Cc: | Triage Stage: | Design decision needed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description
Django currently uses the sha module from the standard library to compute the SHA-1 hash of a password. Developers with particular concerns about security may prefer to use a stronger, more secure hashing algorithm such as SHA-256. Such algorithms are available in the standard library as of Python 2.5, via the hashlib module.
This patch modifies django.contrib.auth.models in two ways. First, it adds support for hashlib and the SHA-224, SHA-256 and SHA-384 algorithms to the check_password function. (For SHA-512 to be supported, the password field of the User model would need to be lengthened.) Second, it modifies the set_password method of the User model to use SHA-256 by default for password hashing, falling back on the sha module if hashlib cannot be imported.
doctests for the check_password function are included with the patch.
Attachments (4)
Change History (12)
by , 19 years ago
| Attachment: | password.diff added |
|---|
comment:1 by , 19 years ago
The original version of the patch can be improved by adding a new setting to django.conf.global_settings, called PASSWORD_HASH_ALGORITHM, and making the set_password method of the User model use this setting.
I'm updating the patch to include this enhancement. PASSWORD_HASH_ALGORITHM is set to a default of 'sha256' in global_settings.py. Django users can redefine it in their settings.py to 'sha224' or 'sha384',
or even to 'sha1' if they wish to preserve the pre-patch behaviour of the admin app. Note, however, that this setting
will be ignored if the hashlib module is not available (i.e. in versions of Python before 2.5).
by , 19 years ago
| Attachment: | password2.diff added |
|---|
Updated diff to add support for stronger password hashes - replaces password.diff
by , 19 years ago
Diff of authentication.txt, documenting the changes made by password2.diff.
comment:2 by , 19 years ago
| Triage Stage: | Unreviewed → Design decision needed |
|---|
Extending the password length to fit SHA-512 now (prior to 1.0) is probably a good idea. I'd also prefer to keep the default in GLOBAL_SETTINGS as sha1 (since this is the current, documented, method), and just document that better hashes are available in python 2.5
But - we'll let core decide on these for now.
follow-up: 5 comment:3 by , 19 years ago
Simon jumped in while I was writing this:
Thanks Nick, but you won't be getting this accepted if you are trying to make a change which requires anything above Python 2.3.
This doesn't mean we couldn't support these secure hashes, they just can't be the default in global_settings.py.
The other consideration (hence my moving to design decision required) is that this puts a partial requirement on >2.3 in the case of databases which containing new hash formats. This might be acceptable, I'm not sure.
(Side note: it's usual practice to just provide one complete patch with both code, tests and documentation changes)
comment:4 by , 19 years ago
| Patch needs improvement: | set |
|---|
comment:5 by , 19 years ago
Replying to SmileyChris:
The other consideration (hence my moving to design decision required) is that this puts a partial requirement on >2.3 in the case of databases which containing new hash formats. This might be acceptable, I'm not sure.
Good point.
How about we add another setting, USE_STRONG_HASHES, set to False in global_settings.py? When this setting is False, the current hashing code is used; when it is set to True explicitly in a project's settings.py, an attempt is made to use hashlib and one of the longer hash algorithms (as specified by PASSWORD_HASH_ALGORITHM).
This approach forces the user to turn on the potentially incompatible behaviour. We could add documentation to carefully explain the potential consequences of doing this. Would that suffice?
I'm happy to rework the patch to follow this slightly different approach, if encouraged to do so :)
comment:6 by , 18 years ago
I like the idea -- there's not reason for Django not to use the strongest hashes available (mmmm... strong hash....). However, the setting is a bit pointless -- there's no reason to use weak hashes if strong ones are available.
So while I'm -1 on this patch, I'd be +0 on a patch that used SHA-256 if hashlib is available, and fell back to SHA1 if not.
comment:7 by , 18 years ago
Firstly, I disagree with jacob. There is a reason for not blindly using the strongest hash available - if run on a Python 2.5 system, it causes the Django auth component of the database to become dependent on Python 2.5.
Replying to the original description: Nick Efford <nick@efford.org>:
(For SHA-512 to be supported, the
passwordfield of theUsermodel would need to be lengthened.)
Not true, just use a different encoding rather than hexidecimal:
>>> import hashlib
>>> from binascii import b2a_base64
>>> hsh = hashlib.new('sha512', 'test')
>>> len(hsh.hexdigest())
128
>>> len(b2a_base64(hsh.digest()).rstrip()) # rstrip because output always ends in \n
88
comment:8 by , 18 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
Chris is completely right here, as I came to realize over in #5600. Marking this one a dup.
diff for django.contrib.auth.models adding support for stronger hashes