Может ли кто-нибудь поделиться рекомендациями по созданию одноразового номера для запроса OAuth в Python?
Каков стандартный метод создания одноразового номера в Python?
Ответы (5)
Вот как это делает python-oauth2:
def generate_nonce(length=8):
"""Generate pseudorandom number."""
return ''.join([str(random.randint(0, 9)) for i in range(length)])
У них также есть:
@classmethod
def make_nonce(cls):
"""Generate pseudorandom number."""
return str(random.randint(0, 100000000))
Кроме того, существует проблема под названием: «make_nonce недостаточно случайна", в которой предлагается :
def gen_nonce(length):
""" Generates a random string of bytes, base64 encoded """
if length < 1:
return ''
string=base64.b64encode(os.urandom(length),altchars=b'-_')
b64len=4*floor(length,3)
if length%3 == 1:
b64len+=2
elif length%3 == 2:
b64len+=3
return string[0:b64len].decode()
А также ссылается на CVE-2013-4347. TL;DR, используйте os.urandom
или абстрактный интерфейс к нему (SystemRandom а>).
Мне нравятся мои lambda
и мне не нужны не буквенно-цифровые символы, поэтому я использовал это:
lambda length: filter(lambda s: s.isalpha(), b64encode(urandom(length * 2)))[:length]
uuid1().get_hex()
. Вы, вероятно, хотите uuid4
или uuid5
, но больше о стандарте UUID, которому соответствует Python, можно найти в RFC4122.
- person A T; 07.10.2015
os.urandom()
и никогда, никогда random.random
или random.randint
. В противном случае у вас могут возникнуть серьезные проблемы с безопасностью.
- person Aur Saraf; 03.03.2016
random.randint
для создания одноразового номера? Спасибо
- person radtek; 03.03.2016
random.randint
злоумышленникам легко догадаться, что ставит под угрозу безопасность. cigital.com/papers/download/developer_gambling.php
- person Aur Saraf; 03.03.2016
floor(a, b)
? В Python3 math.floor
принимает один аргумент.
- person kevr; 14.06.2021
Для большинства практических целей это дает очень хороший одноразовый номер:
import uuid
uuid.uuid4().hex
# 'b46290528cd949498ce4cc86ca854173'
uuid4()
использует os.urandom()
, который является лучшим случайным, который вы можете получить в python.
Nonce следует использовать только один раз, и его трудно предсказать. Обратите внимание, что uuid4()
труднее предсказать, чем uuid1()
, тогда как более поздние более уникальны в глобальном масштабе. Таким образом, вы можете добиться еще большей силы, комбинируя их:
uuid.uuid4().hex + uuid.uuid1().hex
# 'a6d68f4d81ec440fb3d5ef6416079305f7a44a0c9e9011e684e2c42c0319303d'
Хотя этого, вероятно, не существовало на момент создания этого вопроса, Python 3.6 представил секреты модуль, предназначенный для генерации криптографически стойких случайных чисел, подходящих для управления такими данными, как пароли, аутентификация учетной записи, токены безопасности и связанные с ними секреты.
В этом случае можно легко сгенерировать одноразовый номер (здесь строка в кодировке base64):
nonce = secrets.token_urlsafe()
Альтернативы: token_bytes для получения двоичного токена или token_hex, чтобы получить шестнадцатеричную строку.
nonce
зависит от того, как его реализует поставщик токенов (это не является строго частью стандарта JWT). Все провайдеры, которых я видел, с удовольствием используют строки. Важной частью является то, что это одноразовое значение. Цифры, которые только увеличиваются, хороши, но вам нужно решить проблему перезагрузки системы. Обычно проще использовать большую случайную строку.
- person Erdős-Bacon; 17.09.2020
Вот что делает rauth. Здесь нет жестких и быстрых правил. Спецификация не кажется слишком самоуверенной. Ваши ограничения заключаются в том, что значение, являющееся одноразовым номером, должно быть уникальным. В остальном, если поставщик не жалуется, вы можете использовать любой метод, который вам нравится.
.encode('ascii')
, прежде чем передать его sha1
. Вероятно, для совместимости с Python 3?
- person A T; 28.01.2015
Вот несколько идей, которые я получил для электронной почты. generate_nonce исходит из их кода, но я использую generate_nonce_timestamp, для которого я использовал uuid. Это дает мне случайную буквенно-цифровую строку и отметку времени в секундах:
import random
import time
import uuid
def generate_nonce(length=8):
"""Generate pseudo-random number."""
return ''.join([str(random.randint(0, 9)) for i in range(length)])
def generate_timestamp():
"""Get seconds since epoch (UTC)."""
return str(int(time.time()))
def generate_nonce_timestamp():
"""Generate pseudo-random number and seconds since epoch (UTC)."""
nonce = uuid.uuid1()
oauth_timestamp, oauth_nonce = str(nonce.time), nonce.hex
return oauth_nonce, oauth_timestamp
Мне нравится использовать uuid1, так как он генерирует uuid на основе текущего хоста и времени и имеет свойство времени, которое вы можете извлечь, если вам нужно и то, и другое. Для электронной почты вам нужны и временная метка, и одноразовый номер.
Вот что вы получаете:
>>> generate_nonce_timestamp()
('a89faa84-6c35-11e5-8a36-080027c336f0', '136634341422770820')
Если вы хотите удалить -
, используйте nonce.get_hex()
.
uuid1 — генерирует UUID из идентификатора хоста, порядкового номера и текущего времени. Подробнее об uuid.
random.randint
(TL; DR: никогда)
- person Aur Saraf; 03.03.2016