Sól i hash hasła w Pythonie

Ten kod ma zahaszować hasło za pomocą soli. Sól i hashowane hasło są zapisywane w bazie danych. Samo hasło nie jest.

Biorąc pod uwagę delikatny charakter operacji, chciałem się upewnić, że wszystko będzie Koszerne.

Uwaga: używam bezpiecznej wersji url b64encode z przyzwyczajenia.

import hashlib
import base64
import uuid

password = 'test_password'
salt     = base64.urlsafe_b64encode(uuid.uuid4().bytes)


t_sha = hashlib.sha512()
t_sha.update(password+salt)
hashed_password =  base64.urlsafe_b64encode(t_sha.digest())
Author: Chris Dutrow, 2012-03-07

6 answers

EDIT: Ta odpowiedź jest błędna. Nie używaj skrótu kryptograficznego do przechowywania haseł. Użyj hash hasła.


Wygląda mi to dobrze. Jednak jestem prawie pewien, że nie potrzebujesz base64. Możesz to zrobić:
import hashlib, uuid
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(password + salt).hexdigest()

Jeśli nie spowoduje to trudności, możesz uzyskać nieco bardziej wydajne Przechowywanie w bazie danych, przechowując salt i hashowane hasło jako surowe bajty, a nie ciągi szesnastkowe. W tym celu należy zastąpić hex bytes i hexdigest digest.

 32
Author: Taymon,
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-06-07 14:18:40

Mądrą rzeczą nie jest samodzielne pisanie krypto, ale używanie czegoś takiego jak passlib: https://bitbucket.org/ecollins/passlib/wiki/Home

Łatwo jest zepsuć pisanie kodu kryptograficznego w bezpieczny sposób. Paskudne jest to, że w przypadku kodu non crypto często natychmiast zauważasz go, gdy nie działa, ponieważ twój program ulega awarii. Podczas gdy w przypadku kodu kryptograficznego często dowiadujesz się o tym dopiero po tym, jak jest zbyt późno i Twoje dane zostały naruszone. Dlatego myślę, że lepiej jest użyć pakiet napisany przez kogoś innego, kto ma wiedzę na ten temat i który jest oparty na testowanych w bitwie protokołach.

Również passlib ma kilka fajnych funkcji, które sprawiają, że jest łatwy w użyciu, a także łatwy do uaktualnienia do nowszego protokołu hashowania hasła, jeśli stary protokół okaże się uszkodzony.

Również tylko jedna runda sha512 jest bardziej podatna na ataki słownikowe. sha512 został zaprojektowany tak, aby był szybki, a to jest naprawdę złe, gdy próbujesz bezpiecznie przechowywać hasła. Inne ludzie długo i ciężko myśleli o tym wszystkim, więc lepiej skorzystaj z tego.

 43
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
2015-12-30 21:28:36

Bazując na innych odpowiedziach na to pytanie, zaimplementowałem nowe podejście przy użyciu bcrypt.

Dlaczego używać bcrypt

Jeśli dobrze rozumiem, argumentem do użycia bcrypt nad SHA512 jest to, że bcrypt jest zaprojektowany tak, aby był powolny. bcrypt ma również możliwość ustawienia, jak wolno będzie generować hashowane hasło po raz pierwszy:

# The '12' is the number the dictates the 'slowness'
bcrypt.hashpw(password, bcrypt.gensalt( 12 ))

Powolne jest pożądane, ponieważ jeśli złośliwa strona dostanie w swoje ręce tabelę zawierającą zaszyfrowane hasła, to jest to dużo trudniej je deszyfrować.

Implementacja

def get_hashed_password(plain_text_password):
    # Hash a password for the first time
    #   (Using bcrypt, the salt is saved into the hash itself)
    return bcrypt.hashpw(plain_text_password, bcrypt.gensalt())

def check_password(plain_text_password, hashed_password):
    # Check hased password. Useing bcrypt, the salt is saved into the hash itself
    return bcrypt.checkpw(plain_text_password, hashed_password)

Uwagi

Udało mi się dość łatwo zainstalować bibliotekę w systemie linux używając:

pip install py-bcrypt
[7]}jednak miałem więcej problemów z zainstalowaniem go na moich systemach windows. Wygląda na to, że potrzebuje plastra. Zobacz to pytanie Stackoverflow: py-bcrypt instalowanie na win 7 64bit python
 42
Author: Chris Dutrow,
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:34:34

Aby to działało w Pythonie 3, musisz kodować UTF-8 na przykład:

hashed_password = hashlib.sha512(password.encode('utf-8') + salt.encode('utf-8')).hexdigest()

W przeciwnym razie dostaniesz:

Traceback (ostatnie wywołanie last):
Plik"", linia 1, w
hashed_password = hashlib.sha512 (hasło + sól).hexdigest ()
TypeError: Unicode-obiekty muszą być zakodowane przed hashowaniem

 18
Author: Wayne,
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
2013-06-11 14:30:08

Passlib wydaje się być przydatny, jeśli potrzebujesz użyć hashów przechowywanych przez istniejący system. Jeśli masz kontrolę nad formatem, użyj nowoczesnego skrótu, takiego jak bcrypt lub scrypt. W tej chwili bcrypt wydaje się być znacznie łatwiejszy w użyciu od Pythona.

Passlib obsługuje bcrypt i zaleca instalację py-bcrypt jako backend: http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html

Możesz również użyć py-bcrypt bezpośrednio, jeśli nie chcesz instalować passlib. Na readme ma przykłady podstawowego zastosowania.

Zobacz także: Jak używać scrypt do generowania hasha dla hasła i soli w Pythonie

 8
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:13

Nie chcę wskrzeszać starego wątku, ale.. każdy, kto chce skorzystać z nowoczesnego, bezpiecznego rozwiązania, korzysta z argon2.

Https://pypi.python.org/pypi/argon2_cffi

Wygrał konkurs haszowania haseł. ( https://password-hashing.net/) jest łatwiejszy w użyciu niż bcrypt i jest bezpieczniejszy niż bcrypt.

 4
Author: nagylzs,
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-08-14 16:56:25