[Fixed]-Why is there a difference in format of encrypted passwords in Django

1👍

You’ll be fine. You just have some blank passwords in your database.

Going back as far as V0.95, django used the $ separators for delimiting algorithm/salt/hash. These days, django pulls out the algorithm first by looking at what is in front of the first $ and then passes the whole lot to the hasher to decode. This allows for a wider set of formats, including the one for PBKDF2 which adds an extra iterations parameter in this list (as per your first example).

However, it also recognises that some users may not be allowed to login and/or have no password. This is encoded using the second format you’ve seen. As you can see here:

If password is None then a concatenation of UNUSABLE_PASSWORD_PREFIX and a random string will be returned which disallows logins.

You can also see that the random string is exactly 40 characters long – just like your second example.

In short, then, this is all as expected.

0👍

There is no significant difference between User.objects.create_user() and user.set_password() since first uses second.

Basically, passwords are in string with format <algorithm>$<iterations>$<salt>$<hash> according to docs. The differences might come from PASSWORD_HASHERS settings variable. May be one password was created with one hasher and other password with another. But if you’ll keep those hashers in variable mentioned above all should be fine, users will able to change it etc. You can read about it in little notice after bcrypt section.

Also docs for django.contrib.auth package might be helpful too. Link.

UPDATE:

If you find documentation of an old django versions (1.3 for example), you will see that

Previous Django versions, such as 0.90, used simple MD5 hashes without password salts. For backwards compatibility, those are still supported; they’ll be converted automatically to the new style the first time check_password() works correctly for a given user.

So I think that the answer might be somewhere here. But it really depends on how legacy your project is, so you can decide if it’s normal or what. Anyway you can issue check_password() to be sure. Or you can just email your user with "change password please" notification. There are many factors involved really.

Leave a comment