このコードは、パスワードをソルトでハッシュすることになっています。ソルトおよびハッシュされたパスワードはデータベースに保存されています。パスワード自体はそうではありません。
操作のデリケートな性質を考えると、私はすべてがコーシャであることを確認したかった。
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())
編集:この答えは間違っています。 SHA512の1つの反復はfastであり、パスワードハッシュ関数としての使用には不適切です。代わりに、ここで他の回答のいずれかを使用してください。
私は元気そうだ。ただし、実際にはbase64は必要ないと確信しています。あなたはこれを行うことができます:
import hashlib, uuid
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(password + salt).hexdigest()
問題が発生しない場合は、ソルトとハッシュ化されたパスワードを16進文字列ではなく生のバイトとして保存することで、データベースの保存効率をわずかに高めることができます。これを行うには、hex
をbytes
に、hexdigest
をdigest
に置き換えます。
この質問に対する他の回答に基づいて、bcryptを使用した新しいアプローチを実装しました。
私が正しく理解している場合、bcrypt
over SHA512
を使用する引数は、bcrypt
が低速になるように設計されているということです。 bcrypt
には、ハッシュ化されたパスワードを初めて生成するときの遅さを調整するオプションもあります。
# The '12' is the number that dictates the 'slowness'
bcrypt.hashpw(password, bcrypt.gensalt( 12 ))
悪意のある者がハッシュされたパスワードを含むテーブルを手に入れた場合、それらをブルートフォースすることははるかに難しいため、遅いことが望ましいです。
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 hashed password. Using bcrypt, the salt is saved into the hash itself
return bcrypt.checkpw(plain_text_password, hashed_password)
次を使用して、Linuxシステムにライブラリを簡単にインストールできました。
pip install py-bcrypt
しかし、Windowsシステムへのインストールにはさらに苦労しました。パッチが必要なようです。このスタックオーバーフローの質問を参照してください: py-bcrypt win 7 64bit pythonにインストールする
賢いのは、自分で暗号を書くのではなく、passlibのようなものを使うことです: https://bitbucket.org/ecollins/passlib/wiki/Home
安全な方法で暗号コードを書くのは簡単です。厄介なのは、非暗号化コードでは、プログラムがクラッシュして動作しないときにすぐに気付くことが多いということです。暗号コードを使用すると、遅れてデータが危険にさらされた後にのみ発見することがよくあります。そのため、このテーマについて知識があり、戦闘テスト済みのプロトコルに基づいている他の誰かが作成したパッケージを使用する方が良いと思います。
また、passlibには、使いやすく、古いプロトコルが壊れていることが判明した場合に新しいパスワードハッシュプロトコルに簡単にアップグレードできるニースの機能がいくつかあります。
また、sha512の1ラウンドだけが辞書攻撃に対して脆弱です。 sha512は高速になるように設計されており、これはパスワードを安全に保存しようとすると実際には悪いことです。他の人々は、この種の問題すべてについて長い間一生懸命に考えてきたので、あなたはこれをより良く利用する。
これをPython 3で機能させるには、たとえばUTF-8エンコードする必要があります。
hashed_password = hashlib.sha512(password.encode('utf-8') + salt.encode('utf-8')).hexdigest()
それ以外の場合は次のようになります:
トレースバック(最後の最後の呼び出し):
ファイル「」、1行目
hashed_password = hashlib.sha512(password + salt).hexdigest()
TypeError:Unicodeオブジェクトは、ハッシュする前にエンコードする必要があります
passlibは、既存のシステムに保存されているハッシュを使用する必要がある場合に役立つようです。形式を制御できる場合は、bcryptやscryptなどの最新のハッシュを使用します。現時点では、bcryptはpythonから使用する方がはるかに簡単なようです。
passlibはbcryptをサポートしています。py-bcryptをバックエンドとしてインストールすることをお勧めします。 http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html
Passlibをインストールしたくない場合は、 py-bcrypt を直接使用することもできます。 readmeには基本的な使用例があります。
古いスレッドを復活させたくありませんが、...最新の最新の安全なソリューションを使用したい人は、アルゴン2を使用してください。
https://pypi.python.org/pypi/argon2_cffi
パスワードハッシュ化コンテストで優勝しました。 ( https://password-hashing.net/ )bcryptよりも使いやすく、bcryptよりも安全です。
最初にインポート:-
import hashlib, uuid
次に、メソッドでこれに従ってコードを変更します。
uname = request.form["uname"]
pwd=request.form["pwd"]
salt = hashlib.md5(pwd.encode())
次に、データベースのsqlクエリでこのsaltとunameを渡します。ログインの下にはテーブル名があります。
sql = "insert into login values ('"+uname+"','"+email+"','"+salt.hexdigest()+"')"
Python 3.4以降、標準ライブラリのhashlib
モジュールには、安全なパスワードハッシュ用に設計されたである key derivation 関数が含まれています「。
したがって、 hashlib.pbkdf2_hmac
などのいずれかを使用し、 os.urandom
を使用してソルトを生成します。
from typing import Tuple
import os
import hashlib
import hmac
def hash_new_password(password: str) -> Tuple[bytes, bytes]:
"""
Hash the provided password with a randomly-generated salt and return the
salt and hash to store in the database.
"""
salt = os.urandom(16)
pw_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
return salt, pw_hash
def is_correct_password(salt: bytes, pw_hash: bytes, password: str) -> bool:
"""
Given a previously-stored salt and hash, and a password provided by a user
trying to log in, check whether the password is correct.
"""
return hmac.compare_digest(
pw_hash,
hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
)
# Example usage:
salt, pw_hash = hash_new_password('correct horse battery staple')
assert is_correct_password(salt, pw_hash, 'correct horse battery staple')
assert not is_correct_password(salt, pw_hash, 'Tr0ub4dor&3')
assert not is_correct_password(salt, pw_hash, 'rosebud')
ご了承ください:
os.urandom
は常に暗号的に安全なランダム性のソースを使用しますhmac.compare_digest
は、is_correct_password
で使用され、基本的には文字列の単なる==
演算子ですが、短絡する機能がないため、タイミング攻撃の影響を受けません。それは おそらく追加のセキュリティ値を実際に提供しない ですが、それも害はないので、先に進んで使用しました。優れたパスワードハッシュを作成する理論と、パスワードをハッシュするのに適した他の関数のリストについては、 https://security.stackexchange.com/q/211/29805 を参照してください。