2012-06-14 2 views
19

Как previous discussed, электронные письма с подтверждением должны иметь уникальный (практически) недопустимый код - по существу one-time password - в ссылке для подтверждения.UUID.randomUUID() подходит для использования как одноразовый пароль?

The UUID.randomUUID() docs говорят:

идентификатор UUID генерируется с использованием криптографически сильного псевдослучайного числа генератора .

Означает ли это, что случайный генератор UUID в правильно реализованной JVM подходит для использования в качестве уникального (практически) недопустимого OTP?

+2

Вы можете быть заинтересованы в [мой ответ на другой вопрос] (http://stackoverflow.com/a/41156/3474), который даст вам больше безопасности с меньшим количеством цифр ... если это имеет значение. – erickson

+0

Также см. Обсуждение здесь: https://security.stackexchange.com/questions/890/are-guids-safe-for-one-time-tokens –

ответ

4

No. Согласно UUID spec:

Не думайте, что UUID, трудно угадать; они не должны использоваться как возможности безопасности (идентификаторы, чье простое владение предоставляет доступ), например. Предполагаемый источник случайных чисел усугубит ситуацию .

Кроме того, UUID имеют только 16 возможных символов (от 0 до F). Вы можете создать гораздо более компактный и явно защищенный случайный пароль, используя SecureRandom (спасибо @erickson).

import java.security.SecureRandom; 
import java.math.BigInteger; 

public final class PasswordGenerator { 
    private SecureRandom random = new SecureRandom(); 

    public String nextPassword() { 
     return new BigInteger(130, random).toString(32); 
    } 
} 
+5

UUID spec! = Реализация Java. Хотя спецификация не требует, чтобы UUID был защищен, реализация Java фактически обеспечивает 122 бит безопасной случайности. См. Также http://stackoverflow.com/a/7532965/47528 – Dan

+0

Я бы по-прежнему рекомендовал использовать crypto lib явно. – jchook

+1

Да, определенно ;-) Когда дело доходит до безопасности, лучше быть осторожным и явным. Вы не будете использовать UUID.randomUUID() для систем военного класса. Но если вопрос: «Я представляю дыру безопасности, используя UUID.randomUUID() для токенов?» тогда ответ - нет. – Dan

-1

Я думаю, что это должно быть подходящим, поскольку оно генерируется случайным образом, а не с любого конкретного ввода (т. Е. Вы не кормите его именем пользователя или чем-то подобным) - поэтому несколько вызовов этого кода будут давать разные результаты. В нем говорится, что у него 128-битный ключ, поэтому его достаточно долго, чтобы непрактично разорваться.

Вы собираетесь использовать этот ключ для шифрования значения, или вы ожидаете использовать его в качестве фактического пароля? Независимо от того, вам нужно будет повторно интерпретировать ключ в формате, который может быть введен с клавиатуры. Например, выполните преобразование Base64 или Hex или каким-либо образом сопоставьте значения с альфа-числами, иначе пользователь попытается ввести значения байтов, которые не существуют на клавиатуре.

+0

Я планирую внедрить код подтверждения в URL-адрес подтверждения, который кликает получатель электронной почты для подтверждения. Нет необходимости вводить пользователя ... – cqcallaw

-1

Это идеальный пароль как один раз, так как даже я реализовал то же самое для приложения, на котором я работаю. Более того, ссылка, которую вы поделили, говорит все.

0

Если это сгенерировано CSRNG, то оно непредсказуемо и поэтому может быть использовано.

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

UUID также являются длинными строками (128 бит, а затем обычно Base64 (22 символа) или Base16-кодированные (32 символа)) - подумайте о том, насколько удобна ваша система. Лично я использовал CSRNG, чтобы выбрать 8 буквенно-цифровых символов случайным образом и вернуть их.

+0

Я не думаю, что возможность предсказать результаты RNG подразумевает возможности перехвата электронной почты - это просто означает, что RNG плохо реализован :) Кроме того, я не слишком обеспокоен длиной, потому что я ожидаю вставить код в URL-адрес подтверждения, который необходимо посетить, чтобы завершить подтверждение. – cqcallaw

0

Точка случайного кода для ссылки подтверждения заключается в том, что злоумышленник не должен угадывать и прогнозировать значение. Как вы можете видеть, чтобы найти правильный код для вашей ссылки подтверждения, UUID длиной в 128 бит дает 2^128 различных возможных кодов, а именно 340 282 366 920 938 463 463 374 607 431 768 211 456 возможных кодов, которые нужно попробовать. Я думаю, что ваша ссылка на подтверждение не для запуска ядерного оружия, не так ли? Это достаточно сложно для злоумышленника. Это безопасно.

- обновление -

Если вы не доверяете генератор случайных чисел криптостойкие при условии, вы можете поставить некоторые более непредсказуемые параметры с кодом UUID и хэш их. Например,

код = SHA1 (UUID, ПИД-, идентификатор потока, локальный номер порта соединения, температура процессора)

Это делает его еще труднее прогнозировать.

+2

Просто количество генерируемых битов не делает его непредсказуемым. 'java.util.Random' может использоваться для получения 128 бит данных, но это не значит, что это что-то вроде безопасного. –

+2

В настоящее время люди атакуют за деньги, и у вас ограниченный бюджет. Ничто не является нерушимым. Так насколько это безопасно? Точка безопасности - насколько они стоят, чтобы сломать ее, и какую выгоду они могут получить? Если это код для ссылки подтверждения на общем веб-сайте, то это достаточно безопасно.Если это код для ядерного оружия, то я бы так не сказал. Для меня определение безопасности - это затраты на его разрыв >> Ожидание дохода. Когда это стоит слишком много, чтобы сломать его, и небольшой доход, который вы можете сделать, сломав его, тогда это безопасно. –

+0

@LouisWasserman Вы не можете сравнивать 'java.util.Random' с' UUID.randomUUID() ' –

13

Если вы читаете RFC, который определяет UUID и который связан с документами API, вы увидите, что не все биты UUID на самом деле случайны («вариант» и «версия» не являются случайными). поэтому UUID типа 4 (тот тип, который вы собираетесь использовать), если он будет реализован правильно, должен иметь 122 бита (безопасную для этой реализации) случайную информацию из общего размера 128 бит.

так что да, он будет работать, а также 122-битное случайное число от «безопасного» генератора. , но более короткое значение может содержать достаточное количество случайности и может быть проще для пользователя (возможно, я единственный старомодный человек, который все еще читает электронную почту в терминале, но URL-адреса подтверждения, которые обертывают строки, раздражают ... .).

+0

Другие предоставили аналогичные ответы, но это казалось наиболее полным и информативным. Благодарю. – cqcallaw

+7

На самом деле RFC явно предостерегает от использования UUID в качестве токенов безопасности: «Не предполагайте, что UUID трудно угадать, они не должны использоваться в качестве возможностей безопасности (идентификаторы, чье простое владение предоставляет доступ)». Сгенерированный UUID4 ** с безопасным RNG ** будет почти невозможно догадаться, но стандарт явно позволяет использовать небезопасные RNG (!). http://tools.ietf.org/html/rfc4122#section-6 (Извинения за воскрешение очень старого комментария, но безопасность - это забота всех). –

4

Да, с использованием java.util.UUID в порядке. Этого гораздо больше нужно сказать.

Вот мое предложение:

  1. Отправить пользователю ссылку с огромным паролем в нем в качестве URL аргумента.
  2. Когда пользователь нажимает на ссылку, напишите свой сервер, чтобы он определил, правильно ли указан аргумент и что пользователь вошел в систему.
  3. Недействительный UUID через 24 часа после его выпуска.

Это займет определенную работу, но это необходимо, если вы действительно заботитесь о создании надежной и надежной системы.

+1

Ваше предложение - мое точное намерение, за исключением того, что я намерен сделать недействительным UUID как можно скорее когда URL-адрес подтверждения посещен и подтверждение завершено. – cqcallaw

Смежные вопросы