Каков стандартный метод генерации nonce в Python?

Может ли кто-нибудь поделиться рекомендациями по созданию nonce для запроса OAuth в Python?

Ответ 1

Здесь 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 s - и мне не нужны не буквенно-цифровые символы, поэтому я использовал это:

lambda length: filter(lambda s: s.isalpha(), b64encode(urandom(length * 2)))[:length]

Ответ 2

Nonce должен быть как использован только один раз и трудно предсказать:

import uuid

uuid.uuid4().hex
# '12b90b6ffc0e46f788a26f1a6dc246fc'

uuid4() использует os.urandom(), который является лучшим случайным, который вы можете получить в python.

Обратите внимание, что uuid4() сложнее прогнозировать, чем uuid1(), тогда как более поздняя версия более глобально уникальна. Вы можете объединить их для достижения обеих целей:

uuid.uuid4().hex + uuid.uuid1().hex
# 'a6d68f4d81ec440fb3d5ef6416079305f7a44a0c9e9011e684e2c42c0319303d'

Ответ 3

Здесь rauth. Здесь нет настоящих жестких правил. Спекуляция не кажется слишком упрямой. Ваши ограничения заключаются в том, что значение, являющееся nonce, должно быть уникальным. Помимо этого, если поставщик не жалуется, вы можете использовать любой способ, который вам нравится.

Ответ 4

Вот несколько идей, которые я получил для отправки по электронной почте. 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 на основе текущего хоста и времени и имеет свойство time, которое вы можете извлечь, если вам нужны оба. Для отправки по электронной почте вам нужны как временная метка, так и nonce.

Вот что вы получаете:

>>> generate_nonce_timestamp()
('a89faa84-6c35-11e5-8a36-080027c336f0', '136634341422770820')

Если вы хотите удалить -, используйте nonce.get_hex().

uuid1 - создать UUID из идентификатора хоста, порядкового номера и текущего времени. Подробнее о uuid.

Ответ 5

Хотя этого, вероятно, не существовало на момент создания этого вопроса, Python 3.6 представил модуль секретов, который предназначен для генерации криптографически сильных случайных чисел, подходящих для управления данными, такими как пароли, аутентификация учетной записи, токены безопасности и связанные секреты.

В этом случае генерирование одноразового номера может быть легко сгенерировано (здесь строка в кодировке base64):

nonce = secrets.token_urlsafe()

Альтернативными являются token_bytes для получения двоичного токена или token_hex для получения шестнадцатеричной строки.