#algorithm #security #validation
#алгоритм #Безопасность #проверка
Вопрос:
У меня есть проект, которому необходимо выполнить проверку во внешнем интерфейсе для американского номера социального страхования (формат ddd-dd-dddd
). Одним из предложений было бы использовать алгоритм хэширования, но, учитывая крошечный используемый набор символов ( [0-9]
), это было бы катастрофически. Было бы приемлемо с некоторой высокой вероятностью подтвердить правильность числа и позволить серверной части выполнить окончательную ==
проверку, но мне нужно сделать намного лучше, чем «имеет девять цифр» и т.д. И т.п.
В поисках лучших альтернатив я наткнулся на контрольные суммы проверки для номеров ISBN и UPC. Они выглядят как отличная альтернатива с высокой вероятностью успеха во внешнем интерфейсе.
Учитывая эти ограничения, у меня есть три вопроса:
- Есть ли способ доказать, что алгоритм, подобный ISBN13, будет работать с другой категорией данных, такой как SSN, или он более или менее соответствует цели с точки зрения безопасности? Контрольная сумма кажется разумной для моей довольно большой выборки одного реального SSN, но мне бы не хотелось узнать, что по какой-то причине они обычно не применимы.
- Это решаемая проблема где-нибудь, так что я могу просто использовать уже существующую схему проверки, чтобы решить проблему?
- Существуют ли какие-либо такие алгоритмы, которые также легко допускали бы проверку последних 4 цифр SSN, не выдавая слишком много дополнительной информации?
Как всегда, спасибо, Джо
Обновить:
В ответ на вопрос ниже, немного подробнее. У меня есть SSN клиента, введенный ранее, надежно сохраненный на серверной части приложения. Что мне нужно сделать, так это подтвердить (в максимально возможной степени), что клиент снова ввел то же значение на этой странице. Проблема в том, что мне нужно предотвратить случайное раскрытие информации интерфейсу в случае, если какое-либо неавторизованное лицо сможет получить доступ к странице.
Вот почему хэш MD5 / SHA1 неуместен: а именно, что его можно использовать для получения полного SSN без особых трудностей. Контрольная сумма (скажем, по модулю 11) практически не предоставляет информации интерфейсу, в то же время обеспечивая высокую степень точности для проверки поля. Однако, как указано выше, у меня есть опасения по поводу его общей применимости.
Комментарии:
1. Почему использование sha1 было бы катастрофическим?
2. @Nick Это было бы катастрофой, потому что вы могли бы довольно быстро перебирать числа такого размера. Кроме того, SSN — это заданный формат, поэтому не все числа допустимы, что еще больше уменьшает размер поиска. Современное оборудование (особенно графические процессоры) может быстро вычислять огромное количество хэшей, так что это недостаточная защита для личной информации.
3. Я несколько смущен вопросом. Разве вы все равно не передаете SSN открытым текстом?
4. @Joseph Спасибо, теперь я лучше понимаю проблему. Тем не менее, я беспокоюсь об утечке информации любого алгоритма, который вы придумаете. Например, простая контрольная сумма mod 11 все равно «утечет», сократив пространство поиска SSN на 10: 1 — стоит ли эта утечка (для каждого пользователя) небольшой экономии в обратном направлении в менее частом случае, когда пользователь ошибочно вводит SSN? Лично я бы выполнил минимальную проверку на стороне клиента (т.Е. 9 цифр и т.д.), Затем выполнил бы обычную проверку на стороне сервера. Простой и без возможности утечки информации. Если случайному пользователю потребуется повторно отправить, пусть будет так.
5. Я согласен с Эриком. Звучит как преждевременная оптимизация. Вы можете выполнить базовую проверку работоспособности и даже некоторую проверку конкретного шаблона SSN во внешнем интерфейсе, просто используя Regex. Затем просто выполните полную проверку — в конечном итоге вам все равно придется это сделать, функция, которая проверяет что-то вроде SSN, вероятно, должна вести на другую страницу, и большинство клиентов, вероятно, получат свой ssn правильно с первого раза. Таким образом, сохраняется только случайный переход туда и обратно. Обходные пути и веб-приложения — это факт жизни. Наверняка в вашем приложении есть что-то еще, более достойное оптимизации?
Ответ №1:
Википедия — не лучший источник для такого рода вещей, но, учитывая это предостережение, http://en.wikipedia.org/wiki/Social_Security_number говорит
В отличие от многих подобных чисел, контрольная цифра не включена.
Но перед этим в нем упоминаются некоторые широко используемые фильтры:
SSA публикует последний номер группы, используемый для каждого номера области. Поскольку номера групп распределяются по обычному (если необычному) шаблону, можно идентифицировать неотправленный SSN, который содержит недопустимый номер группы. Несмотря на эти меры, многие мошеннические SSN нелегко обнаружить, используя только общедоступную информацию. Для этого существует множество онлайн-сервисов, которые обеспечивают проверку SSN.
Комментарии:
1. Спасибо за ответ, Майк. Хотя я, вероятно, мог бы разумно определить, является ли число SSN, мне нужно знать, является ли число вашим SSN.
2. @Joseph, когда что-то на запрашивающем конце HTTP-соединения предоставляет вам SSN, вы хотите проверить, работает ли докладчик от имени реального гражданина / резидента США, которому этот SSN был выдан и впоследствии не отозван?
3. Прошу прощения за неопределенность. У меня уже есть SSN клиента (надежно сохраненный на серверной части), и мне нужно подтвердить, что SSN, который они вводят во внешнем интерфейсе, совпадает с тем, который у меня есть в записи, не раскрывая интерфейсу никакой дополнительной информации, которая у меня есть (на случай, если сеанс каким-либо образом скомпрометирован).
4. @Джозеф, ах. Итак, олицетворение не является проблемой, потому что вы уже выполнили некоторую аутентификацию? Но вы не доверяете интерфейсу с полной строкой в любой таблице информации об учетной записи? Итак, вы хотите функцию issnofcurrentuser (ssn), которая возвращает логическое значение или асинхронный эквивалент? Является ли подслушивание проблемой или любой канал, по которому вы отправляете SSN, уже защищен от подслушивания?
5. Олицетворение является потенциальной проблемой (например, если сеанс скомпрометирован), и вы правы в том, что я не доверяю клиенту данные. Ваш функциональный сигнал примерно правильный, но я сомневаюсь в асинхронных вызовах из-за временной задержки для обхода. Я бы пожертвовал некоторыми ложными срабатываниями (думал, что это правильно, оказалось неправильно) из соображений скорости. Перехват выходит за рамки вопроса, но он защищен с помощью обычного браузера SSL.
Ответ №2:
Повторяем ваши основные требования:
- Достаточно надежная контрольная сумма для защиты от простых человеческих ошибок.
- «Ожидаемая» контрольная сумма отправляется с сервера -> клиент, позволяя проверку на стороне клиента.
- Контрольная сумма не должна раскрывать слишком много информации о SSN, чтобы минимизировать утечку конфиденциальной информации.
Я мог бы предложить использовать криптографический has (SHA-1 и т.д.), Но не отправляйте клиенту полное значение хэша. Например, отправьте только младшие 4 бита из 160-битного результата хэширования[1]. Отправляя 4 бита контрольной суммы, ваши шансы обнаружить ошибку ввода данных равны 15/16 — это означает, что вы будете обнаруживать ошибки в 93% случаев. Обратная сторона, однако, заключается в том, что вы «слили» достаточно информации, чтобы уменьшить их SSN до 1/16 пространства поиска. Вам решать, стоит ли удобство проверки на стороне клиента этой утечки.
Настраивая количество отправляемых битов «контрольной суммы», вы можете выбирать между удобством для пользователя (т. е. обнаружением ошибок) и утечкой информации.
Наконец, учитывая ваши требования, я подозреваю, что этот компромисс между удобством и утечкой является неотъемлемой проблемой: конечно, вы могли бы использовать более сложный алгоритм крипто-запроса / ответа (как проницательно предлагает Ник Оделл). Однако для этого потребуется отдельный запрос в оба конца — то, чего, как вы сказали, вы пытались избежать в первую очередь.
[1] В хорошей крипто-хэш-функции все выходные цифры хорошо рандомизированы из-за эффекта лавины, поэтому конкретные цифры, которые вы выбираете, не имеют особого значения — все они фактически случайны.
Ответ №3:
Простое решение. Возьмите число mod 100001 в качестве контрольной суммы. Существует вероятность 1/100_000, что вы случайно получите правильную контрольную сумму с неправильным номером (и это будет очень устойчиво к одно- или двузначным ошибкам, устраняющим ошибки), и 10 000 возможных SSN, которые могли бы быть, чтобы вы не раскрыли SSN злоумышленнику.
Единственным недостатком является то, что 10 000 возможных других SSN легко вычисляются. Если пользователь может получить последние 4 SSN из другого источника, то он, вероятно, сможет вычислить SSN. Если вас это беспокоит, то вам следует взять номер SSN пользователя, добавить соль и хэшировать его. И намеренно используют дорогостоящий алгоритм хэширования для этого. (Вы можете просто повторить более дешевый алгоритм, такой как MD5, фиксированное количество раз, чтобы увеличить стоимость.) Затем используйте только определенное количество битов. Суть здесь в том, что, хотя кто-то, безусловно, может просмотреть все миллиарды возможных SSN, чтобы получить ограниченный список возможностей, это обойдется ему дороже. Надеюсь, достаточно, чтобы они не беспокоились.