Django password and security

Posted by jme on Thu, 27 Jan 2022 23:48:53 +0100

Django password and security

Cryptography is a technique used to confuse (information represented by public and standard information coding is transformed into communication by a transformation means)
Information code that cannot be read by anyone other than both parties). Is to transform normal (identifiable) information into unrecognized information.
But part of this unrecognized information is cracking (password leakage).

The design of password shall comply with Kirchhoff principle:

Even if any details of the cryptosystem are known, it should be secure as long as the key (also known as key or secret key) is not leaked.

How does Django store passwords?

The password attribute of the User object is in the following format:

<algorithm>$<iterations>$<salt>$<hash>

Including: hash algorithm $number of algorithm iterations (number of times running on hash) $random Salt $password hash value

Django uses PASSWORD_HASHERS settings to select the algorithm, PASSWORD_HASHERS is a configuration item in the settings configuration file, which is a list of hash algorithm classes supported by Django,
The first entry will be used to store the password. If you want to use different algorithms, you need to modify PASSWORD_HASHERS ,
Your algorithm is preferred in the list

Note: Django version 1.3 and before uses sha1 algorithm to encrypt user password, and the storage format is (< algorithm > $< salt > $< hash >):

1.4 and later versions select settings by default PASSWORD_ HASHERS[0]
As an algorithm for encrypting user passwords (the default is PBKDF2PasswordHasher (pbkdf2_sha256)), it is a mechanism recommended by NIST (National Institute of standards and Technology). The storage format is (< algorithm > $< iterations > $< salt > $< hash >):

What is PBKDF2?

PBKDF2 algorithm encrypts the password through multiple hashes. The principle is to hash through password and salt, and then use the result as salt
hash with password and repeat this process for many times to generate the final ciphertext. The addition of salt value will also increase the difficulty of "rainbow table" attack,
This process may reach thousands of times. Reverse cracking is too difficult. It may take hundreds of years to crack a password, so PBKDF2 algorithm is safe**

How should Hasher choose?

Django provides a lot of password_ The comparison between hashers and the built-in Hasher of Django is as follows:

But not all are recommended. At present, the most recommended is the default PBKDF2PasswordHasher, because it is safe enough.
At the same time, for some easy to crack encryption algorithms, such as md5 and sha1 (because they can pass through Precomputed hash chain set and rainbow table Therefore, for some encryption algorithms with low security, we should upgrade them accordingly.

What methods does Hasher have?

hasher provides the following methods:

  • Password encryption

  • Password verification

  • Change the judgment of iterations

    Compare the number of iterations configured by Hasher with the number of iterations in the database password

  • Additional hash ing times

check_ Clever design of password

1. Get the required hasher
2. Get old password hasher
3. Is it necessary to strengthen the algorithm and increase the complexity
4. Judge whether the encryption algorithm changes
5. password verifiers  verify
7. Extra hash frequency

(Applications: for example, to improve the number of iterations and password security,
Changed Hasher of iterations Quantity, when it is detected that it is inconsistent with the quantity in the database,
It will be carried out additionally iterations - int(database iterations) (iterations)

6. Change old encryption algorithm

(Application: when the user logs in, the password will be automatically upgraded and only need to be adjusted PASSWORD_HASHERS Sequence, such as: sha1 -> pbkdf2_sha1)

How to upgrade the password of the system

If the company wants you to upgrade your password system, what should you do? For example, sha1 used before

When the user logs in, the password is automatically upgraded

Just adjust PASSWORD_HASHERS sequence, such as: SHA1 - > pbkdf2_ SHA1, after the user's previous password verification passes

When the user logs in, the password will be upgraded

If the database has an old and inefficient hash algorithm, such as MD5 or SHA1, you may want to upgrade the hash instead of waiting for the user to log in
Upgrade (if a user no longer logs in to the site and the database is always the old password, the password will not be upgraded)
Steps:

   1. Take out the user password in the database, encrypt the password encrypted at this time again, and generate pbkdf2_wrapped_sha1 Your vest code, At this time, the vest password format in the database is: pbkdf2_wrapped_sha256$216000$4YfO8YTUgTO9$xxxxxxx
   2. PASSWORD_HASHERS Add processing intermediate in PBKDF2WrappedSHA1PasswordHasher class
   3. When the user logs in, go to PBKDF2WrappedSHA1PasswordHasher of encode Method, encrypt the password into vest password
   4. Then perform password verification. The vest passwords are consistent twice and pass the password verification
   5. Trigger login to change the password and change the old encryption algorithm conditions. Change the password to: pbkdf2_sha256$216000$GS9f0OKOxxQE$xxxxxx

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-k0eqsndn-1624274177083)( http://share-images.chunyu.mobi//donghao/20210621190611.png )]

Refer to the following codes:

from django.contrib.auth import get_user_model
from django.core.management import BaseCommand
from django.contrib.auth.hashers import (
    PBKDF2PasswordHasher, SHA1PasswordHasher,
)
class PBKDF2WrappedSHA1PasswordHasher(PBKDF2PasswordHasher):
    algorithm = 'pbkdf2_wrapped_sha1'

    def encode_sha1_hash(self, sha1_hash, salt, iterations=None):
        return super().encode(sha1_hash, salt, iterations)

    def encode(self, password, salt, iterations=None):
        """
        The password of the user when logging in should be updated once sha1 hash Operation, and then convert it into pbkdf2_sha256 hash password
        """
        _, _, sha1_hash = SHA1PasswordHasher().encode(password, salt).split('$', 2)
        return self.encode_sha1_hash(sha1_hash, salt, iterations)


class Command(BaseCommand):
    def handle(self, *args, **options):
        """
        sha1 Password upgrade -> pbkdf2_sha1
        """
        User = get_user_model()
        users = User.objects.filter(password__startswith='sha1$')
        hasher = PBKDF2WrappedSHA1PasswordHasher()
        for user in users:
            algorithm, salt, sha1_hash = user.password.split('$', 2)
            user.password = hasher.encode_sha1_hash(sha1_hash, salt)
            user.save(update_fields=['password'])

How does Django do password verification?

Built in password verifier

Django provides pluggable password authentication. Multiple password validators can be configured at the same time. Django contains some validators, which can also be very simple to implement custom validators.
Configure Auth in settings file_ PASSWORD_ VALIDATORS. It is only used for Django Admin and command commands to create and modify user passwords

The functions provided are:

  • CommonPasswordValidator: pass some common password verification with the definition. common-passwords.txt defines nearly 2w common passwords.
  • NumericPasswordValidator: isdigit for digital judgment
  • MinimumLengthValidator: len for length comparison
  • Userattributesimilarity validator: the standard library of python used to check the similarity with the user attributes to be compared (such as username, email, etc.) Difflib To check the text similarity.

Third party package Django password validators

  • PasswordCharacterValidator
    Specify at least numbers, letters, case numbers, etc. to improve password security
  • UniquePasswordsValidator
    Verify whether the user has ever used the password. It cannot be set to the previously set password n times (n > = 0)

Custom password verifier

The following methods need to be implemented:

1.AUTH_PASSWORD_VALIDATORS Add verifier Name(Import path), OPTIONS (__init__Method parameters)

2.Class implementation validate,get_help_text method

3.Can add password_changed Method will be called after the password modification is successful.

Topics: Python Django