Пин Генерация - PullRequest
       44

Пин Генерация

16 голосов
/ 01 января 2009

Я хочу разработать систему, в которой мне нужно назначить каждому пользователю уникальный пин-код для обеспечения безопасности. Пользователь будет вводить этот пин-код только для идентификации себя. Таким образом, я не хочу, чтобы пользователь мог угадать пин-код других пользователей. Предполагая, что максимальное количество пользователей, которое у меня будет, составляет 100000, как долго должен быть этот пин-код?

например. 1234 4532 3423

Должен ли я генерировать этот код по какому-то алгоритму? Или я должен генерировать его случайно?

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

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

Большое спасибо.

UPDATE

После прочтения всех постов ниже, я хотел бы добавить некоторые подробности.

  1. Я пытаюсь достичь чего-то очень похожего на скретч-карту.
  2. Пользователь получает карточку, которую он / она должен поцарапать, чтобы найти пин-код.
  3. Теперь, используя этот пин-код, пользователь должен иметь доступ к моей системе.

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

Спасибо всем за ваши удивительные ответы снова.

Ответы [ 11 ]

9 голосов
/ 01 января 2009

4 случайных цифр должно быть достаточно, если вы добавите их к уникальному известному идентификатору пользователя (все еще может быть числом) [в соответствии с рекомендациями starblue]

Генератор псевдослучайных чисел также должен быть в порядке. Вы можете сохранить их в БД, используя обратимое шифрование (AES) или одностороннее хеширование

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

Более 6 цифр, и люди забудут их или, что еще хуже, напишут их на заметке на мониторе.

Если предположить, что учетная запись блокируется с 3 неверными попытками, то при наличии 4-значного PIN-кода плюс компонента идентификатора пользователя UserId (999999) + PIN-код (1234) дает 3/10000 шансов угадать. Это приемлемо? Если нет, сделайте штифт длиной 5 и получите 3/100000

8 голосов
/ 01 января 2009

Могу ли я предложить альтернативный подход? Взгляните на Perfect Paper Passwords и на производные , которые он запросил.

Вы можете использовать это «как есть» для создания одноразовых ПИН-кодов или просто для создания одного ПИН-кода для каждого пользователя.

Имейте также в виду, что дубликаты ПИН-кодов сами по себе не являются проблемой: любая атака должна была бы просто попробовать несколько идентификаторов пользователя.

(Предупреждение о пробеге: я определенно не эксперт по безопасности.)


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

Вам необходимо выбрать длину ПИН-кода, чтобы вероятность угадывания действительного ПИН-кода была меньше 1 / (количество попыток, от которых вы можете защититься). Так, например, если у вас 1 миллион действительных ПИН-кодов и вы хотите защитить от 10000 догадок, вам понадобится 10-значный ПИН-код.

Если вы используете версию системы Perfect Paper Passwords Джона Грэхема-Камминга, вы можете:

  1. Сконфигурируйте это для (скажем) десятизначных десятичных пинов
  2. Выберите секретную IV / ключевую фразу
  3. Генерация (скажем) первого миллиона паролей (/ PIN)

Я подозреваю, что это общая процедура, которую можно, например, использовать для создания 25-буквенно-цифровых идентификаторов продуктов.

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

4 голосов
/ 02 января 2009

Множество отличных ответов: простой, эффективный и элегантный!

Я предполагаю, что приложение несколько похоже на лотерею, так как каждый пользователь получает скретч-карту и использует ее, чтобы спросить ваше приложение, "если он уже выиграл!" Итак, с этой точки зрения на ум приходит несколько новых вопросов:

Военный набор , или его эквивалент в Интернете: может ли мошеннический пользователь повторно нажимать на ваше приложение, скажем, угадывая каждый 10-значный номер подряд? Если это возможно, подумайте об ограничении количества попыток из определенного места. Эффективным способом может быть просто отказаться отвечать больше, чем, скажем, на одну попытку каждые 5 секунд с одного и того же IP-адреса. Это делает атаку с помощью машины неэффективной и позволяет избежать проблемы блокировки .

Проблема блокировки : Если вы заблокируете учетную запись навсегда после любого количества неудачных попыток, вы склонны к атакам типа "отказ в обслуживании" . Вышеуказанный злоумышленник может эффективно заблокировать каждого пользователя , если вы не активируете учетные записи через некоторое время. Но это проблема только в том случае, если ваши PIN-коды состоят из очевидного объединения идентификатора пользователя + ключ, поскольку злоумышленник может попробовать каждый ключ для данного идентификатора пользователя. Этот метод также значительно сокращает пространство клавиш, потому что только несколько цифр PIN действительно случайны. С другой стороны, если ПИН-код представляет собой просто последовательность случайных цифр, блокировка должна применяться только к исходному IP-адресу. (Если попытка не удалась, действительная учетная запись не затрагивается, что бы вы «заблокировали»?)

Хранение данных : если вы действительно строите какую-то лотерейно-подобную систему, вам нужно только сохранить выигрышные PIN-коды ! Когда пользователь вводит PIN-код, вы можете выполнить поиск в относительно небольшом списке PIN-кодов / призов (или вашего аналога). Вы можете идентифицировать «потерянный» и недействительный PIN-код одинаково с помощью сообщения «Извините, удачи в следующий раз» или приза «по умолчанию», если экономика верна.

Удачи!

4 голосов
/ 01 января 2009

Если предположить, что максимум 100 000 пользователей, то они могут иметь уникальные ПИН-коды с 0-99 999, т.е. 5 цифр.

Однако это облегчит угадывание ПИН-кодов с максимальным количеством пользователей. Если вы можете ограничить количество попыток ввода PIN-кода, вы можете использовать более короткий PIN-код. например. максимум 10 неудачных попыток на IP в день.

Это также зависит от ценности того, что вы защищаете, и от того, насколько катастрофическим он был бы, если бы вышел нечетный.

Я бы пошел на 9 цифр, если вы хотите, чтобы оно было коротким, или на 12 цифр, если вы хотите немного больше защиты от автоматического угадывания.

Чтобы сгенерировать PIN-коды, я бы взял версию с высоким разрешением , а также немного salt и, возможно, псевдослучайное число, сгенерировав hash и используйте первые 9 или 12 цифр. Убедитесь, что между новыми поколениями ПИН-кодов имеется разумная и случайная задержка, чтобы не генерировал их в цикле , и по возможности сделайте их инициированными пользователем.

например. Слева (Sha1 (DateTime + Salt + PseudoRandom), 9)

2 голосов
/ 08 марта 2012

Если вы используете алгоритмы генератора случайных чисел, то у вас никогда не будет ПИН-кода типа «00038384882», начинается с 0 (нули), потому что целые числа никогда не начинаются с "0". Ваш ПИН-код должен начинаться с 1-9 цифр, кроме 0.

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

Я думаю, что вам нужно поместить 0-9 чисел в хеш, получить случайным образом из хеша и сделать ваш строковый PIN-код.

2 голосов
/ 01 января 2009

Вопрос должен звучать так: «Сколько предположений в среднем необходимо, чтобы найти действительный ПИН-код, по сравнению с тем, сколько предположений делают злоумышленники?»

Если вы генерируете 100 000 5-значных кодов, то, очевидно, это займет 1 предположение. Вряд ли это будет достаточно хорошо.

Если вы сгенерируете 100 000 n-значных кодов, то потребуется (n-5) ^ 10 догадок. Чтобы понять, достаточно ли это хорошо, вам нужно подумать, как ваша система реагирует на неправильные предположения.

Если злоумышленник (или все злоумышленники вместе взятые) могут делать 1000 предположений в секунду, то ясно, что n должно быть достаточно большим, чтобы остановить решительного злоумышленника. Если вы навсегда заблокируете их IP-адрес после 3 неправильных предположений, то, поскольку данный злоумышленник вряд ли будет иметь доступ к более, например, 1000 IP-адресам, n = 9 будет достаточно, чтобы помешать почти всем злоумышленникам. Очевидно, что если вы столкнетесь с распределенными атаками или атаками ботнета, то 1000 IP-адресов на каждого злоумышленника больше не являются безопасным предположением.

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

Учитывая ваш случай использования скретч-карты, если пользователи собираются использовать систему в течение длительного времени, я бы рекомендовал разрешить им (или заставить их) «обновить» свой PIN-код до имени пользователя и пароля по своему выбору после первое использование системы. Тогда вы получаете обычные преимущества имени пользователя / пароля, не отказываясь от простоты первого использования, просто набрав номер с карты.

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

1 голос
/ 21 января 2009

Если вы хотите сгенерировать пин-коды типа скретч-карты, вы должны использовать большие числа, длиной около 13 цифр; а также они должны быть похожи на номера кредитных карт, с контрольной суммой или контрольной цифрой, встроенной в сам номер. У вас должен быть алгоритм для генерации булавки на основе некоторых исходных данных, которые могут быть последовательностью чисел. Полученный пин-код должен быть уникальным для каждого числа в последовательности, поэтому, если вы генерируете 100 000 пин-кодов, все они должны быть разными. Таким образом, вы сможете проверить число не только проверяя его по базе данных, но и сначала проверив его.

Однажды я написал что-то для этой цели, я не могу дать вам код, но общая идея такова:

  • Подготовьте пробел из 12 цифр
  • Отформатируйте число в виде пяти цифр (от 00000 до 99999) и распределите его по пробелу определенным образом. Например, число 12345 может быть распространено как __3_5_2_4__1. Вы можете варьировать способ распределения числа в зависимости от того, является ли оно четным или нечетным числом или кратным 3 и т. Д.
  • Основываясь на значении определенных цифр, сгенерируйте больше цифр (например, если третья цифра четная, затем создайте нечетное число и поместите его в первое открытое пространство, в противном случае создайте четное число и поместите его во второе открытое пробел, например _83_5_2_4__1
  • После того как вы сгенерировали 6 цифр, у вас будет только одно открытое пространство. Вы всегда должны оставлять одно и то же открытое пространство (например, предпоследний пробел). Вы разместите проверочную цифру в этом месте.
  • Чтобы сгенерировать проверочную цифру, вы должны выполнить некоторые арифметические операции над сгенерированным вами числом, например, сложить все цифры в нечетных позициях и умножить их на какое-то другое число, затем вычесть все цифры в четных позициях и наконец, сложив все цифры вместе (вы должны немного изменить алгоритм в зависимости от значения определенных цифр). В конце концов у вас есть проверочная цифра, которую вы включаете в сгенерированный пин-код.

Так что теперь вы можете проверить ваши сгенерированные пин-коды. Для данного пин-кода вы генерируете контрольную цифру и сравниваете ее с той, которая включена в пин-код. Если все в порядке, вы можете извлечь исходный номер, выполнив обратные операции.

Это звучит не очень хорошо, потому что это выглядит как безопасность через неизвестность, но это единственный способ, которым вы можете использовать это. Для кого-то не возможно угадать пин-код, но, будучи 12-значным кодом с проверочной цифрой, это будет очень сложно, так как вам нужно попробовать 1 000 000 000 000 комбинаций, а у вас просто 100 000 действительных пин-кодов, поэтому для каждого действительного пин-кода есть 10 000 000 недействительных.

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

0 голосов
/ 02 января 2009

Я делал это раньше с PHP и базой данных MySQL. У меня была функция перестановок, которая сначала обеспечивала бы возможность создания числа необходимых кодов - $ n, длиной $ l, с количеством символов, $ c - до начала процесса генерации.

Затем я сохранял каждый новый код в базе данных и позволял ему сообщать мне через ошибки UNIQUE KEY, что произошло столкновение (дубликат). Затем продолжайте, пока я не наберу $ n числа успешно созданных кодов. Конечно, вы можете сделать это в памяти, но я хотел сохранить коды для использования при слиянии почты MS Word. Итак ... тогда я экспортировал их в виде файла CSV.

0 голосов
/ 01 января 2009

Существует разница между угадыванием PIN-кода целевого пользователя и любого действительного пользователя. Из вашего варианта использования кажется, что ПИН-код используется для получения доступа к определенному ресурсу, и именно этот ресурс может преследовать злоумышленник, а не конкретные идентификационные данные пользователей. Если это действительно так, вам нужно будет ввести действительные номера PIN в достаточном количестве разреженный среди всех возможных номеров с одинаковыми цифрами.

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

Теперь предположим, что ваш ПИН-код имеет энтропию N , и в вашей системе есть 2 ^ M пользователей ( M ), вероятность что случайное предположение даст правильный PIN-код: 2 ^ {MN} . (Извините за латексные обозначения, я надеюсь, что это достаточно интуитивно понятно). Затем оттуда вы можете определить, достаточно ли мала вероятность, учитывая N и M , или вычислить необходимые N из требуемой вероятности и M .

Существуют различные способы создания ПИН-кодов, чтобы вам не приходилось запоминать каждый сгенерированный ПИН-код. Но вам понадобится очень длинный PIN-код, чтобы сделать его безопасным. Это, вероятно, не то, что вы хотите.

0 голосов
/ 01 января 2009

Должен ли я генерировать этот код через некоторые своего рода алгоритм?

Нет. Это будет предсказуемо.

Или я должен генерировать его случайно?

Да. Используйте криптографический генератор случайных чисел или предоставьте пользователю возможность выбрать собственный PIN-код.

Теоретически 4 цифры будет достаточно, поскольку эмитентам карт банкоматов удается поддерживать очень большое сообщество именно этим (и, очевидно, они не могут быть и не должны быть уникальными). Однако в этом случае вам следует ограничить количество попыток ввода PIN-кода и заблокировать их после такого количества попыток, как это делают банки. И вам также следует попросить пользователя предоставить идентификатор пользователя (в случае банкомата, который фактически находится на карте).

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

Вы не должны хранить ПИН-код в открытом виде нигде (например, солить и хэшировать его, как пароль), однако, учитывая короткий набор символов и ограниченный набор символов, он всегда будет уязвим для поиска методом "грубой силы", учитывая простой способ чтобы проверить это.

Существуют и другие схемы, которые можно использовать, если вы можете рассказать нам больше о своих требованиях (это веб-приложение? Встроенная система? И т. Д.).

...