Najbezpieczniejsza metoda Pythona do przechowywania i pobierania haseł z bazy danych

Szukam przechowywania nazw użytkowników i haseł w bazie danych i zastanawiam się, jaki jest najbezpieczniejszy sposób na to. Wiem, że muszę gdzieś użyć soli, ale nie jestem pewien, jak bezpiecznie wygenerować ją lub jak zastosować ją do zaszyfrowania hasła. Przykładowy kod Pythona byłby bardzo mile widziany. Dzięki.

Author: Magnus Hoff, 2010-04-03

5 answers

Zapisz hasło + sól jako hash i sól. Spójrz jak Django to robi: basic docs i source . W db przechowują <type of hash>$<salt>$<hash> w pojedynczym polu znaku. Można również przechowywać trzy części w oddzielnych polach.

Funkcja ustawiająca hasło:

def set_password(self, raw_password):
    import random
    algo = 'sha1'
    salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
    hsh = get_hexdigest(algo, salt, raw_password)
    self.password = '%s$%s$%s' % (algo, salt, hsh)

Get_hexdigest jest tylko cienką owijką wokół niektórych algorytmów haszujących. Możesz użyć hashlib do tego. Coś jak hashlib.sha1('%s%s' % (salt, hash)).hexdigest()

Oraz funkcja sprawdzania hasła:

def check_password(raw_password, enc_password):
    """
    Returns a boolean of whether the raw_password was correct. Handles
    encryption formats behind the scenes.
    """
    algo, salt, hsh = enc_password.split('$')
    return hsh == get_hexdigest(algo, salt, raw_password)
 39
Author: rz.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 10:25:48

Myślę, że najlepiej jest użyć pakietu dedykowanego do hashowania haseł takich jak passlib: http://packages.python.org/passlib / z powodów, jak wyjaśniłem tutaj: https://stackoverflow.com/a/10948614/893857

 16
Author: M.D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:02

Odpowiedziałem na to tutaj: https://stackoverflow.com/a/18488878/1661689 , podobnie jak @Koffie.

Nie wiem, jak wystarczająco podkreślić, że przyjęta odpowiedź nie jest Bezpieczna. Jest lepszy niż zwykły tekst i lepszy niż niesolony hash, ale nadal jest bardzo podatny na ataki słownikowe, a nawet brutalne. Zamiast tego, proszę używać wolnego KDF Jak bcrypt (lub co najmniej PBKDF2 z 10 000 iteracjami)

 15
Author: Terrel Shumway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:17

Jeśli masz wystarczającą kontrolę nad obydwoma punktami końcowymi aplikacji, najlepszym sposobem jest użycie PAK-z + .

(Edited: the original version recommended SRP but PAK-Z+ has a proof of security.)

 3
Author: Paul Crowley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-27 05:45:56

Tutaj jest prostszy sposób (wzięty z effbota), pod warunkiem, że hasła o długości większej niż 8 nie będą problemem*:

import crypt

import random, string

def getsalt(chars = string.letters + string.digits):
    # generate a random 2-character 'salt'
    return random.choice(chars) + random.choice(chars)

Do wygenerowania hasła:

crypt.crypt("password", getsalt())

*: hasło o długości większej niż 8 jest usuwane z prawej strony do długości 8 znaków

 0
Author: llazzaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-26 04:28:23