secrets --- 機密を扱うために安全な乱数を生成する

Added in version 3.6.

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


The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.

In particular, secrets should be used in preference to the default pseudo-random number generator in the random module, which is designed for modelling and simulation, not security or cryptography.

参考

PEP 506

乱数

The secrets module provides access to the most secure source of randomness that your operating system provides.

class secrets.SystemRandom

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

secrets.choice(seq)

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

secrets.randbelow(exclusive_upper_bound)

[0, exclusive_upper_bound) の範囲のランダムな整数を返します。

secrets.randbits(k)

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

トークンの生成

The secrets module provides functions for generating secure tokens, suitable for applications such as password resets, hard-to-guess URLs, and similar.

secrets.token_bytes(nbytes=None)

Return a random byte string containing nbytes number of bytes.

If nbytes is not specified or None, DEFAULT_ENTROPY is used instead.

>>> token_bytes(16)
b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
secrets.token_hex(nbytes=None)

Return a random text string, in hexadecimal. The string has nbytes random bytes, each byte converted to two hex digits.

If nbytes is not specified or None, DEFAULT_ENTROPY is used instead.

>>> token_hex(16)
'f9bf78b9a18ce6d46a0cd2b0b86df9da'
secrets.token_urlsafe(nbytes=None)

Return a random URL-safe text string, containing nbytes random bytes. The text is Base64 encoded, so on average each byte results in approximately 1.3 characters.

If nbytes is not specified or None, DEFAULT_ENTROPY is used instead.

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

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

To be secure against brute-force attacks, tokens need to have sufficient randomness. Unfortunately, what is considered sufficient will necessarily increase as computers get more powerful and able to make more guesses in a shorter period. As of 2015, it is believed that 32 bytes (256 bits) of randomness is sufficient for the typical use-case expected for the secrets module.

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

Otherwise, if no argument is provided, or if the argument is None, the token_* functions uses DEFAULT_ENTROPY instead.

secrets.DEFAULT_ENTROPY

Default number of bytes of randomness used by the token_* functions.

The exact value is subject to change at any time, including during maintenance releases.

その他の関数

secrets.compare_digest(a, b)

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

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

This section shows recipes and best practices for using secrets to manage a basic level of security.

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

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

注釈

アプリケーションは、平文であろうと暗号化されていようと、 復元可能な形式でパスワードを保存 してはいけません。パスワードは暗号学的に強い一方向 (非可逆) ハッシュ関数を用いてソルトしハッシュしなければなりません。

アルファべットと数字からなり、小文字を少なくとも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()