# `secrets` --- Generate secure random numbers for managing secrets

バージョン 3.6 で追加.

ソースコード: Lib/secrets.py

`secrets` モジュールを使って、パスワードやアカウント認証、セキュリティトークンなどの機密を扱うのに適した、暗号学的に強い乱数を生成することができます。

特に、 `random` モジュールのデフォルトの擬似乱数ジェネレータよりも `secrets` を使用するべきです。 `random` モジュールはモデル化やシミュレーション向けで、セキュリティや暗号学的に設計されてはいません。

参考

PEP 506

## 乱数

`secrets` モジュールは OS が提供する最も安全な乱雑性のソースへのアクセスを提供します。

class secrets.SystemRandom

  OS が提供する最も高品質なソースを用いて乱数を生成するためのクラスです。更に詳しいことについては `random.SystemRandom` を参照してください。

secrets.choice(sequence)

  空でないシーケンスから要素をランダムに選択して返します。

secrets.randbelow(n)

  Return a random int in the range [0, n).

secrets.randbits(k)

  ランダムな k ビットの整数を返します。

## トークンの生成

`secrets` モジュールはパスワードのリセットや想像しにくい URL などの用途に適した、安全なトークンを生成するための関数を提供します。

secrets.token_bytes([nbytes=None])

  nbytes バイトを含むバイト文字列を返します。nbytes が `None` の場合や与えられなかった場合は妥当なデフォルト値が使われます。

      >>> token_bytes(16)
      b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'

secrets.token_hex([nbytes=None])

  十六進数のランダムなテキスト文字列を返します。文字列は nbytes のランダムなバイトを持ち、各バイトは二つの十六進数に変換されます。nbytes が `None` の場合や与えられなかった場合は妥当なデフォルト値が使われます。

      >>> token_hex(16)
      'f9bf78b9a18ce6d46a0cd2b0b86df9da'

secrets.token_urlsafe([nbytes=None])

  nbytes のランダムなバイトを持つ URL 安全なテキスト文字列を返します。テキストは Base64 でエンコードされていて、平均的に各バイトは約 1.3 文字になります。 nbytes が `None` の場合や与えられなかった場合は妥当なデフォルト値が使われます。

      >>> token_urlsafe(16)
      'Drmhze6EPcv0fN_81Bj-nA'

### トークンは何バイト使うべきか？

総当たり攻撃 に耐えるには、トークンは十分にランダムでなければなりません。残念なことに、コンピュータの性能が向上し、より短時間により多くの推測ができるようになるにつれ、十分とされるランダムさというのは必然的に増えます。2015 年の時点で、`secrets` モジュールに想定される通常の用途では、32 バイト (256 ビット) のランダムさは十分と考えられています。

独自の長さのトークンを扱いたい場合、様々な `token_*` 関数に `int` 引数で渡すことで、トークンに使用するランダムさを明示的に指定することができます。引数はランダムさのバイト数として使用されます。

それ以外の場合、すなわち引数がない場合や `None` の場合、`token_*` 関数は妥当なデフォルト値を代わりに使います。

注釈

デフォルトはメンテナンスリリースの間を含め、いつでも変更される可能性があります。

## その他の関数

secrets.compare_digest(a, b)

  文字列または bytes-like オブジェクト a と b が等しければ `True` を、そうでなければ `False` を返します。比較は タイミング攻撃 のリスクを減らす "定数時間比較" の方法で行われます。詳細については `hmac.compare_digest()` を参照してください。

## レシピとベストプラクティス

この節では `secrets` を使用してセキュリティの基礎的なレベルを扱う際のレシピとベストプラクティスを説明します。

8文字のアルファベットと数字を含むパスワードを生成するには:

    import string
    import secrets
    alphabet = string.ascii_letters + string.digits
    password = ''.join(secrets.choice(alphabet) for i in range(8))

注釈

Applications should not store passwords in a recoverable format, whether plain text or encrypted. They should be salted and hashed using a cryptographically strong one-way (irreversible) hash function.

アルファべットと数字からなり、小文字を少なくとも1つと数字を少なくとも3つ含む、10文字のパスワードを生成するには:

    import string
    import secrets
    alphabet = string.ascii_letters + string.digits
    while True:
        password = ''.join(secrets.choice(alphabet) for i in range(10))
        if (any(c.islower() for c in password)
                and any(c.isupper() for c in password)
                and sum(c.isdigit() for c in password) >= 3):
            break

XKCD スタイルのパスフレーズ を生成するには:

    import secrets
    # On standard Linux systems, use a convenient dictionary file.
    # Other platforms may need to provide their own word-list.
    with open('/usr/share/dict/words') as f:
        words = [word.strip() for word in f]
        password = ' '.join(secrets.choice(words) for i in range(4))

パスワードの復元用途に適したセキュリティトークンを含む、推測しにくい一時 URL を生成するには:

    import secrets
    url = 'https://example.com/reset=' + secrets.token_urlsafe()