Рекомендации по генерации токенов SessionId/Authentication
Я видел людей, использующих UUID для генерации токена аутентификации. Однако в RFC 4122 указано, что
Не предполагайте, что UUID трудно угадать; они не должны использоваться как средства обеспечения безопасности (идентификаторы, чьи простые владения предоставляются доступ), например.
Мне было интересно, какие алгоритмы используются, например, в Java и .NET для генерации SessionId/AuthenticationToken. Является ли UUID действительно непригодным для этих целей в приложении, которое имеет более чем средние потребности в безопасности?
Ответы
Ответ 1
UUID
генерация случайная, но случайная с плохой энтропией означает, что вы в конечном итоге легко угадаете UUID
s. Если вы используете хороший генератор случайных чисел, вы можете сгенерировать UUID
, который можно использовать для сеансов. Уловка к этому, однако, заключается в том, что UUID
не имеет встроенной защиты от повторного воспроизведения, фальсификации, фиксации и т.д., Вы должны обрабатывать это самостоятельно (читай: UUID сам по себе не должен быть считается действительным идентификатором сеанса). Тем не менее, здесь хороший фрагмент того, как вы создадите безопасный UUID
с помощью python
:
Уникальный идентификатор сеанса в python
Ответ 2
Отказ от ответственности: я не криптограф
Не думайте, что UUID трудно угадать; например, их не следует использовать в качестве средств защиты (идентификаторов, чье простое владение предоставляет доступ).
Хотя в целом это так, следует также отметить, что некоторые системы генерируют UUID с использованием криптографически сильных генераторов псевдослучайных чисел (например, Java):
public static UUID randomUUID()
Статическая фабрика для получения UUID типа 4 (псевдослучайно сгенерированного). UUID генерируется с использованием криптографически сильного генератора псевдослучайных чисел.
Возвращает:
Случайно сгенерированный UUID
Мне было интересно, какие алгоритмы используются, например, в Java и .NET для генерации SessionId/AuthenticationToken.
Tomcat не использует UUID в качестве маркеров сеанса, но использует безопасный случайный генератор SHA1PRNG для создания идентификаторов сеансов:
/**
* The name of the algorithm to use to create instances of
* {@link SecureRandom} which are used to generate session IDs. If no
* algorithm is specified, SHA1PRNG is used. To use the platform default
* (which may be SHA1PRNG), specify the empty string. If an invalid
* algorithm and/or provider is specified the {@link SecureRandom} instances
* will be created using the defaults. If that fails, the {@link
* SecureRandom} instances will be created using platform defaults.
*/
private String secureRandomAlgorithm = "SHA1PRNG";
Это просто значение по умолчанию, и вы можете предоставить свой собственный генератор идентификаторов сеансов, реализовав интерфейс org.apache.catalina.SessionIdGenerator
.
Помимо использования случайно сгенерированной строки в идентификаторе сеанса, стандартная реализация также добавляет jvmRoute
к идентификаторам сеанса, которые она генерирует:
Идентификатор маршрутизации для этого экземпляра Tomcat. Он будет добавлен к идентификатору сеанса для обеспечения возможности маршрутизации без сохранения состояния с помощью балансировщиков нагрузки. Детали того, как jvmRoute будет включен в id, зависят от реализации. См. Стандартную реализацию для поведения по умолчанию.
Сила SHA1PRNG
уже обсуждалась здесь.
Действительно ли UUID не подходит для этих целей в приложении, которое требует более чем средних требований безопасности?
UUID Java почти так же безопасны, как генератор идентификаторов сеансов Tomcat по умолчанию, который генерирует 16-байтовые длинные идентификаторы сеансов:
Tomcat:
/** Number of bytes in a session ID. Defaults to 16. */
private int sessionIdLength = 16;
java.util.UUID в OpenJDK 7:
public static UUID randomUUID() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
}
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
Но вы можете настроить генератор идентификаторов сеансов Tomcat на использование более 16 байт для дополнительной безопасности.
Дальнейшее чтение: