シークレット—シークレットを管理するための安全な乱数を生成します—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/library/secrets
移動先:案内検索

secrets —シークレットを管理するための安全な乱数を生成します

バージョン3.6の新機能。


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



secrets モジュールは、パスワード、アカウント認証、セキュリティトークン、および関連するシークレットなどのデータの管理に適した、暗号的に強力な乱数を生成するために使用されます。

特に、 secrets は、 random モジュールのデフォルトの疑似乱数ジェネレーターよりも優先して使用する必要があります。これは、セキュリティや暗号化ではなく、モデリングとシミュレーション用に設計されています。

も参照してください

PEP 506


乱数

secrets モジュールは、オペレーティングシステムが提供する最も安全なランダム性のソースへのアクセスを提供します。

class secrets.SystemRandom
オペレーティングシステムが提供する最高品質のソースを使用して乱数を生成するためのクラス。 詳細については、 random.SystemRandom を参照してください。
secrets.choice(sequence)
空でないシーケンスからランダムに選択された要素を返します。
secrets.randbelow(n)
[0、 n )の範囲のランダムなintを返します。
secrets.randbits(k)
k ランダムビットでintを返します。


トークンの生成

secrets モジュールは、パスワードのリセットや推測しにくいURLなどのアプリケーションに適した安全なトークンを生成するための関数を提供します。

secrets.token_bytes([nbytes=None])

nbytes バイト数を含むランダムなバイト文字列を返します。 nbytesNoneであるか、指定されていない場合、適切なデフォルトが使用されます。

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

ランダムなテキスト文字列を16進数で返します。 文字列には nbytes のランダムなバイトがあり、各バイトは2桁の16進数に変換されます。 nbytesNoneであるか、指定されていない場合、適切なデフォルトが使用されます。

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

nbytes ランダムバイトを含むランダムなURLセーフテキスト文字列を返します。 テキストはBase64でエンコードされているため、平均して各バイトは約1.3文字になります。 nbytesNoneであるか、指定されていない場合、適切なデフォルトが使用されます。

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

トークンは何バイトを使用する必要がありますか?

ブルートフォース攻撃から保護するには、トークンに十分なランダム性が必要です。 残念ながら、コンピュータがより強力になり、より短い期間でより多くの推測を行うことができるようになるにつれて、十分であると見なされるものは必然的に増加します。 2015年の時点で、 secrets モジュールに期待される一般的なユースケースには、32バイト(256ビット)のランダム性で十分であると考えられています。

独自のトークン長を管理したい場合は、さまざまなtoken_*関数に int 引数を指定することで、トークンに使用されるランダム性の量を明示的に指定できます。 その引数は、使用するランダム性のバイト数と見なされます。

それ以外の場合、引数が指定されていない場合、または引数がNoneの場合、token_*関数は代わりに適切なデフォルトを使用します。

ノート

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


その他の機能

secrets.compare_digest(a, b)
文字列 ab が等しい場合は、Trueを返します。それ以外の場合は、タイミング攻撃のリスクを減らす方法で、Falseを返します。 。 詳細については、 hmac.compare_digest()を参照してください。


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

このセクションでは、シークレットを使用して基本レベルのセキュリティを管理するためのレシピとベストプラクティスを示します。

8文字の英数字のパスワードを生成します。

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

ノート

アプリケーションは、プレーンテキストであろうと暗号化されていようと、パスワードを回復可能な形式保存してはなりません。 それらは、暗号的に強力な一方向(不可逆)ハッシュ関数を使用してソルトおよびハッシュする必要があります。


少なくとも1つの小文字、少なくとも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://mydomain.com/reset=' + secrets.token_urlsafe()