secrets — 비밀 관리를 위한 안전한 난수 생성

버전 3.6에 추가.

소스 코드: Lib/secrets.py


secrets 모듈은 암호, 계정 인증, 보안 토큰 및 관련 비밀과 같은 데이터를 관리하는 데 적합한 암호학적으로 강력한 난수를 생성하는 데 사용됩니다.

특히, secrets는 보안이나 암호화가 아닌 모델링과 시뮬레이션용으로 설계된 random 모듈의 기본 의사 난수 생성기보다 먼저 사용해야 합니다.

더 보기

PEP 506

난수

secrets 모듈은 운영 체제가 제공하는 가장 안전한 무작위 소스에 대한 액세스를 제공합니다.

class secrets.SystemRandom

운영 체제에서 제공하는 최고 품질의 소스를 사용하여 난수를 생성하는 클래스. 자세한 내용은 random.SystemRandom를 참조하십시오.

secrets.choice(sequence)

Return a randomly chosen element from a non-empty 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 무작위 바이트가 있으며, 각 바이트는 두 자리 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)

Return True if strings or bytes-like objects a and b are equal, otherwise False, using a “constant-time compare” to reduce the risk of timing attacks. See hmac.compare_digest() for additional details.

조리법과 모범 사례

이 절에서는 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.

적어도 하나의 소문자, 적어도 하나의 대문자 및 적어도 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()