Генерировать уникальные pin-коды (6 цифр), используя текущее время и имя пользователя пароль?

#c #one-time-password

#c #одноразовый пароль

Вопрос:

Мне нужно использовать текущее время, потому что позже другой программе потребуется знать, когда я сгенерировал pin-код и каковы имя пользователя и пароль.

Краткие сведения:

  • Имя пользователя пароль текущее время = pin [6 цифр]

  • Обратный, сгенерированный PIN-код, мне нужно знать, какой именно, и проверить, прошла ли уже 1 минута.

Я не прошу прямой код, но мне нужно знать лучший, не сказать лучший, хороший способ / алгоритм для этого. Спасибо (кстати, я новичок в cpp)

Редактировать:

Прошу прощения за то, что не прояснил ситуацию. На самом деле, мне не нужен OTP, после генерации pin-кода другая программа должна будет запускаться следующим образом: validate {имя пользователя} {пароль} {pin}

Комментарии:

1. Все, о чем я могу думать прямо сейчас, — это хэш-функция, которая генерирует 6-значную строку в базе 64.

2. @Red вы не сможете расшифровать это впоследствии

3. @sehe Что вы имеете в виду под OTP is purely random and secret ?

Ответ №1:

999999 минут, что дает ~ 694 дня, ~ 1,9 года. Итак, если бы вы использовали всю доступную энтропию только для записи текущего времени, вы бы изменили значение менее чем за 2 года.

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

С 6 десятичными разрядами вы можете хранить около 19 бит данных. Таким образом, вам нужно убедиться, что у вас есть надежная защита от перебора на стороне сервера, иначе будет тривиально пробовать все возможные комбинации.

Одноразовые пароли не имеют внутренней структуры, поддающейся декодированию, они обычно используются в дополнение к обычному паролю в качестве второго фактора при аутентификации. Тогда они могут быть основаны на времени, как вы предлагаете, но не являются обратимыми — другой конец также имеет секретный ключ и может сам генерировать возможный список.

Так, например, помимо ввода имени пользователя и (обычного) пароля, пользователь вводит значение из токена, который генерируется как AES(secretkey, currentminute) , а сервер вычисляет AES(secretkey, currentminute) и AES(secretkey, currentminute-1) т.д., Чтобы сравнить значение с. Он также может записывать, какой токен соответствует, чтобы он записывал оценку точности часов токена, что допускает некоторый сдвиг часов токена, если он используется достаточно часто. Чтобы решить, как наилучшим образом использовать 19 бит, которые у вас есть в 6-значном pin-коде, вам понадобится кто-то, кто является настоящим криптографом, поскольку я бы предположил, что простое усечение может быть небезопасным.

Комментарии:

1. Спасибо за ответ. Для AES (secretkey, currentminute) AES может быть md5 или что-то в этом роде? Есть ли у вас какая-либо хэш-функция, которая возвращает только цифры? Я думаю, md5 возвращает буквенно-цифровую строку

2. @generator Оба AES и MD5 просто возвращают вам биты, как вы их кодируете, зависит от вас. Вам нужно использовать шифрование, а не хеширование, поскольку вам нужно иметь общий секрет между двумя концами (поскольку все знают, какова текущая минута).

Ответ №2:

Добавил мой предыдущий комментарий к ответу, как запоздалую мысль:

Я почти уверен, что называть это «otp» обманчиво. OTP является чисто случайным и секретным.

То, что вы описываете, является простым хэшем.

Вы могли бы

  MD5(username password_hash (seconds_past_1970%60))
  

Я уверен, что помимо использования шифрования с открытым ключом вместо пароля, это более или менее так, как это делают ключи RSA.

Редактировать О да: будет довольно тривиально сгенерировать 6 цифр из результирующего хэша 🙂

Комментарии:

1. как бы вы выполнили обратный шаг?

2. @duedlOr: Вы не можете отменить процесс. 6 цифр не могут содержать достаточно информации для кодирования всей информации. Учтите, что пользователь может использовать более 6 цифр только для пароля.

3. @David: Цель, которую я предполагал, заключалась в проверке PIN-кода на сервере на основе известного общего секрета. Я предположил, что OP знает, что это не является (не должно быть) обратимым, и он на самом деле имел в виду повторить шаги на сервере (зная входные данные и время). Очевидно, что 6 цифр далеко не достаточно для его кодирования, если только не осталось энтропии и ввод очень прост… это привело бы к тому, что pin-код раскрывал секреты почти в виде обычного текста. Поскольку это абсолютно бесполезно, мой ответ кажется правильным 🙂