34

ユーザー名とパスワードをデータベースに保存しようとしていて、そのための最も安全な方法は何か疑問に思っています。どこかでソルトを使用する必要があることは知っていますが、ソルトを安全に生成する方法や、パスワードを暗号化するためにソルトを適用する方法がわかりません。いくつかのサンプルPythonコードをいただければ幸いです。ありがとう。

4

6 に答える 6

41

パスワードとソルトをハッシュとソルトとして保存します。Django がどのようにそれを行うかを見てみましょう: basic docssource . <type of hash>$<salt>$<hash>データベースでは、単一の char フィールドに格納 されます。3 つのパーツを別々のフィールドに保管することもできます。

パスワードを設定する関数:

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 は、一部のハッシュ アルゴリズムの薄いラッパーです。そのためにhashlibを使用できます。何かのようなものhashlib.sha1('%s%s' % (salt, hash)).hexdigest()

そして、パスワードをチェックする関数:

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)
于 2010-04-03T17:50:07.483 に答える
16

これには、パスワードのハッシュ化専用の関数を使用するのが最善だと思います。ここでいくつかの理由を説明 ます。のような暗号的に安全なランダムソースからソルトを取得する必要があることにも言及していますos.urandom()

于 2012-06-08T12:22:37.583 に答える
15

私はここでこれに答えました:https://stackoverflow.com/a/18488878/1661689、そして@Koffieもそうでした。

受け入れられた答えが安全ではないことを十分に強調する方法がわかりません。プレーンテキストよりも優れており、ソルトなしのハッシュよりも優れていますが、それでも辞書やブルートフォース攻撃に対して非常に脆弱です. 代わりに、bcrypt のようなSLOW KDF (または少なくとも10,000 回の反復を伴う PBKDF2)を使用してください。

于 2013-08-28T17:42:49.447 に答える
3

アプリケーションの両方のエンドポイントを十分に制御できる場合、絶対に最適な方法はPAK-Z+を使用することです。

(編集: 元のバージョンではSRPが推奨されていましたが、PAK-Z+ にはセキュリティの証明があります。)

于 2010-04-07T10:46:24.427 に答える
0

これはより簡単な方法です (effbot から取得)。8 文字を超える長さのパスワードは問題になりません*:

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)

パスワードを生成するには:

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

*: 8 文字を超える長さのパスワードは、右側から 8 文字の長さに削除されます

于 2013-01-05T02:49:10.453 に答える