web-dev-qa-db-ja.com

ランダム文字列vsハッシュ(ランダム文字列)?

ワンタイムトークンサービスを実装しています。これらのワンタイムトークンのそれぞれは、それに関連付けられたサーバー側のデータ/アクション(たとえば、「電子メールの確認」アクション)を表すため、私のWebサービスはセッションなしでそれらを受信したときに確認してアクションを実行できます。 (メールの確認リンク内から、QRコードスキャンから; ...)

これらのトークンは、推測や偽造が非常に困難なはずです。長いランダム文字列(/ dev/urandomから)で十分だと思います。しかし https://en.wikipedia.org/wiki//dev/random から:

/ dev/randomに対応するものは/ dev/urandom( "unlimited" [5]/non-blocking random source [4])で、内部プールを再利用してより多くの疑似ランダムビットを生成します。つまり、呼び出しはブロックされませんが、出力には/ dev/randomからの対応する読み取りよりも少ないエントロピーが含まれる可能性があります。/dev/urandomは依然としてほとんどの暗号化目的に適した疑似乱数ジェネレータとして意図されていますが、一部の人々は/ dev/urandomを長期暗号化キーの生成に推奨されていないと主張しています[誰?]。ただし、エントロピープールが予測不可能になると、ビット数を減らしてもセキュリティがリークしないため、これは一般に当てはまりません。

また、私はwerkzeugのセッションでいくつかのコードを読みました https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/contrib/sessions.py

_def _urandom():
    if hasattr(os, 'urandom'):
        return os.urandom(30)
    return text_type(random()).encode('ascii')

def generate_key(salt=None):
    if salt is None:
        salt = repr(salt).encode('ascii')
    return sha1(b''.join([
        salt,
        str(time()).encode('ascii'),
        _urandom()
    ])).hexdigest()
_

だから私の質問です:そのようなhash(time()+urandom())は純粋なurandom()よりも「ランダムな」文字列を生成しますか?ここでハッシュ関数を使用する目的は何ですか?

8
jayven

実際のランダムデータは100%予測不可能です。 urandomのようなインターフェースは、これに加えて均一な分布を提供します。つまり、予測できないランダムな値を取得するだけでなく、すべての値が同じ確率を持ちます。すでにそのような高品質のランダム性のソースがある場合、ハッシュはそれをこれ以上改善しません。つまり、hash(time()+urandom())urandom()だけよりも優れたものにはなりません。

ただし、random()が使用できない場合、コード例は単純なurandom()関数にフォールバックします。これは通常、前の値を十分に知っている場合に値が何らかの形で予測可能である高速疑似乱数ジェネレータのみです。したがって、出力をソルトおよび時間と一緒にハッシュすることは、疑似乱数ジェネレータのみに直面したときに出力を予測不可能にする試みである可能性があります。また、出力に実際のランダム性を追加するわけではありませんが、元の疑似乱数値に戻すことが難しくなるため、基になる疑似乱数ジェネレータに対する攻撃を使用することが難しくなります。実際のランダムデータの場合、入力データはすでに完全に予測不可能であり、以前の値がわかっている場合に次のランダム値を計算する方法がないため、このような種類の保護は必要ありません。

6
Steffen Ullrich