Лучшие практики по созданию токенов OAuth?

100

Я понимаю, что спецификация OAuth ничего не указывает о происхождении кода ConsumerKey, ConsumerSecret, AccessToken, RequestToken, TokenSecret или Verifier, но мне любопытно, есть ли какие-либо передовые методы создания значительно безопасных токенов (особенно Token / Секретные комбинации).

На мой взгляд, есть несколько подходов к созданию токенов:

  1. Просто используйте случайные байты, храните в БД, связанной с потребителем / пользователем
  2. Хешировать некоторые данные пользователя / потребителя, хранить в БД, связанной с потребителем / пользователем
  3. Шифрование пользовательских / потребительских данных

Преимущества (1) в том, что база данных является единственным источником информации, который кажется наиболее безопасным. Было бы труднее провести атаку против (2) или (3).

Хеширование реальных данных (2) позволит повторно сгенерировать токен из предположительно уже известных данных. На самом деле может не дать никаких преимуществ для (1), так как в любом случае нужно будет хранить / искать. Более интенсивная загрузка ЦП, чем (1).

Шифрование реальных данных (3) позволит расшифровать известную информацию. Это потребует меньше места для хранения и потенциально меньше запросов, чем (1) и (2), но также потенциально менее безопасно.

Есть ли другие подходы / преимущества / недостатки, которые следует учитывать?

РЕДАКТИРОВАТЬ: еще одно соображение заключается в том, что в токенах ДОЛЖНО быть какое-то случайное значение, поскольку должна существовать возможность истечения срока действия и перевыпуска новых токенов, поэтому она не должна состоять только из реальных данных.

Следите за вопросами :

Есть ли минимальная длина токена, чтобы сделать его криптографически безопасным? Насколько я понимаю, более длинные Token Secrets создадут более безопасные подписи. Это понимание правильное?

Есть ли преимущества в использовании одной кодировки перед другой с точки зрения хеширования? Например, я вижу множество API, использующих шестнадцатеричное кодирование (например, строки GUID). В алгоритме подписи OAuth токен используется как строка. С шестнадцатеричной строкой доступный набор символов будет намного меньше (более предсказуемым), чем, скажем, с кодировкой Base64. Мне кажется, что для двух строк равной длины у строки с большим набором символов будет лучшее / более широкое распределение хешей. Мне кажется, это улучшит безопасность. Верно ли это предположение?

Спецификация OAuth поднимает именно эту проблему в 11.10 Entropy of Secrets .

Макками
источник
Почему именно шифрование? Недостаточно хеширования? Если для пароля достаточно простого хеширования, разве не должно быть лучше для более длинных токенов доступа?
AlikElzin-kilaka
Прошло 7,5 лет с тех пор, как я задал этот вопрос. Честно говоря, не могу вспомнить.
mckamey
1
Повторное чтение, хеширование и шифрование - это два разных подхода. Шифрование позволит серверу получать некоторую информацию без поиска в БД. Это был один компромисс из многих.
mckamey

Ответы:

93

OAuth ничего не говорит о токене, за исключением того, что с ним связан секрет. Так что все схемы, которые вы упомянули, будут работать. Наш токен развивался по мере роста сайтов. Вот версии, которые мы использовали раньше,

  1. Наш первый токен - это зашифрованный BLOB с именем пользователя, секретом токена, сроком действия и т.д. Проблема в том, что мы не можем отозвать токены без какой-либо записи на хосте.

  2. Поэтому мы изменили его, чтобы хранить все в базе данных, а токен - это просто случайное число, используемое в качестве ключа к базе данных. Он имеет индекс имени пользователя, поэтому легко перечислить все токены для пользователя и отозвать его.

  3. У нас довольно мало хакерских действий. При использовании случайного числа мы должны обратиться к базе данных, чтобы узнать, действителен ли токен. Итак, мы снова вернулись к зашифрованному BLOB. На этот раз токен содержит только зашифрованное значение ключа и срок действия. Таким образом, мы можем обнаруживать недействительные или просроченные токены, не обращаясь к базе данных.

Некоторые детали реализации, которые могут вам помочь,

  1. Добавьте версию в токен, чтобы вы могли изменить формат токена, не нарушая существующие. Все наши токены имеют первый байт в качестве версии.
  2. Используйте безопасную для URL-адресов версию Base64 для кодирования BLOB, чтобы вам не приходилось сталкиваться с проблемами кодирования URL-адресов, что затрудняет отладку с помощью подписи OAuth, поскольку вы можете увидеть базовую строку с тройным кодированием.
ZZ Coder
источник
2
Отлично, спасибо. Идея версии хорошая. У меня есть поддерживающий URL-адрес Base64, но я бы хотел, чтобы у меня была строго буквенно-цифровая кодировка для еще более удобного чтения.
mckamey
Не думал об этом раньше, очень интересно! Я планировал использовать кэширование ключей APC, чтобы избежать ненужной нагрузки на БД, прежде чем я прочитал это. По-прежнему не уверен, что это может быть медленнее, чем поиск в общей памяти APC (по крайней мере, на 2-й, 3-й и т. Д. Запрос в разумные сроки).
Philzen