Лучший способ предотвратить повторное использование кредитных карт - PullRequest
17 голосов
/ 19 сентября 2008

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

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

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

Ребята, вы видите какие-нибудь недостатки в этом методе? Это стандартный способ решения этой проблемы?

Ответы [ 15 ]

17 голосов
/ 19 сентября 2008

Давайте немного посчитаем: номера кредитных карт состоят из 16 цифр. Первые семь цифр - это номера «основных отраслей» и эмитента, а последняя цифра - контрольная сумма luhn. Это оставляет 8 цифр «свободными», что в сумме составляет 100 000 000 номеров счетов, умноженных на количество номеров потенциальных эмитентов (которые вряд ли будут очень высокими). Существуют реализации, которые могут выполнять миллионы хешей в секунду на повседневном оборудовании, поэтому независимо от того, что вы делаете, это не будет большой проблемой для грубой силы.

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

Хранение кредитных карт с использованием простого однократного прохождения алгоритма хеширования, даже если оно засолено, является безрассудным. Слишком просто взломать номера кредитных карт, если хэши скомпрометированы.

...

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

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

10 голосов
/ 19 сентября 2008

Люди думают над дизайном этого, я думаю. Используйте соленый, высокозащищенный (например, «вычислительно дорогой») хеш, такой как sha-256, с уникальной солью для каждой записи.

Сначала вы должны выполнить недорогую проверку высокой точности, а затем выполнить окончательную проверку высокой стоимости только в том случае, если эта проверка ударит.

Шаг 1:

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

Шаг 2:

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

Последние 4 цифры cc # являются наиболее уникальными (отчасти потому, что они также включают контрольную цифру LUHN), поэтому процент выполненных вами глубоких проверок, которые в конечном итоге не будут совпадать (частота ложных срабатываний) быть очень, очень низким (доля процента), что экономит вам огромное количество накладных расходов по сравнению с наивным «делай проверку хеша каждый раз».

5 голосов
/ 12 августа 2009

Do not хранит простой SHA-1 номера кредитной карты, это будет way , который легко взломать (особенно, если известны последние 4 цифры). У нас была такая же проблема в моей компании: вот как мы ее решили.

Первое решение

  1. Для каждой кредитной карты мы сохраняем последние 4 цифры, дату истечения срока действия, длинную случайную соль (длиной 50 байт) и соленый хэш номера CC. Мы используем алгоритм хэширования bcrypt, потому что он очень безопасен и может быть настроен так, чтобы загружать процессор так, как вам хочется. Мы настроили его на очень дорого (около 1 секунды на хеш на нашем сервере!). Но я думаю, что вы могли бы использовать SHA-256 вместо этого и повторять столько раз, сколько необходимо.
  2. Когда вводится новый номер CC, мы начинаем с поиска всех существующих номеров CC, которые заканчиваются одинаковыми 4 цифрами и имеют одинаковую дату истечения срока действия. Затем для каждой совпадающей CC мы проверяем, соответствует ли ее сохраненный соленый хеш соленому хешу, вычисленному из его соли и нового номера CC. Другими словами, мы проверяем, действительно ли hash(stored_CC1_salt+CC2)==stored_CC1_hash.

Поскольку в нашей базе данных примерно 100 тыс. Кредитных карт, нам необходимо вычислить около 10 хешей, поэтому мы получим результат примерно за 10 секунд. В нашем случае это нормально, но вы можете немного настроить bcrypt. К сожалению, если вы это сделаете, это решение будет менее безопасным. С другой стороны, если вы настроите bcrypt на более интенсивную загрузку процессора, для сопоставления номеров CC потребуется больше времени.

Хотя я считаю, что это решение на способ лучше, чем простое хранение несоленного хэша номера CC, оно не помешает очень мотивированному пирату (которому удастся получить копию базы данных) разорвать одну кредитную карту в среднем от 2 до 5 лет. Так что, если у вас есть 100 тыс. Кредитных карт в вашей базе данных, и если у пирата есть процессор лот , он может каждый день восстанавливать несколько номеров кредитных карт!

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

Второй раствор

Просто попросите поставщика платежных услуг создать псевдоним для вашей кредитной карты.

  1. для каждой кредитной карты вы просто сохраняете все, что хотите сохранить (например, последние 4 цифры и срок действия) плюс псевдоним номера кредитной карты.
  2. при вводе нового номера кредитной карты вы связываетесь с вашим платежным провайдером и даете ему номер CC (или вы перенаправляете клиента на провайдера платежей, и он вводит номер CC непосредственно на веб-сайте провайдера платежей). Взамен вы получите псевдоним кредитной карты! Вот и все. Конечно, вы должны убедиться, что ваш платежный провайдер предлагает эту опцию и что сгенерированный псевдоним действительно безопасен (например, убедитесь, что они не просто вычисляют SHA-1 по номеру кредитной карты!). Теперь пират должен сломать вашу систему плюс систему вашего провайдера платежей, если он хочет восстановить номера кредитных карт.

Это просто, это быстро, это безопасно (ну, по крайней мере, если ваш провайдер платежей). Единственная проблема, которую я вижу, это то, что она связывает вас с вашим платежным провайдером.

Надеюсь, это поможет.

3 голосов
/ 19 сентября 2008

PCI DSS утверждает, что вы можете хранить PAN (номера кредитных карт), используя сильный односторонний хэш. Они даже не требуют, чтобы это было солено. Тем не менее, вы должны засолить его уникальным значением для каждой карты. Дата истечения - хорошее начало, но, возможно, слишком короткое. Вы можете добавить другие данные с карты, например, об эмитенте. Вы не должны использовать CVV / защитный номер, так как вам не разрешено его хранить. Если вы используете дату истечения срока действия, то, когда держателю карты будет выдана новая карта с тем же номером, она будет считаться другой картой. Это может быть хорошо или плохо в зависимости от ваших требований.

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

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

2 голосов
/ 11 августа 2014

Я считаю, что нашел надежный способ решить эту проблему. Кто-нибудь, пожалуйста, исправьте меня, если в моем решении есть изъян.

  1. Создайте защищенный сервер на EC2, Heroku и т. Д. Этот сервер будет служить ОДНОЙ и ТОЛЬКО одной цели: хэширование вашей кредитной карты.
  2. Установите на этом сервере защищенный веб-сервер (Node.js, Rails и т. Д.) И настройте вызов API REST.
  3. На этом сервере используйте уникальную соль (1000 символов) и SHA512 - 1000 раз.

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

2 голосов
/ 19 сентября 2008

@ Кори Р. Кинг

SHA 1 не сломан, как таковой. В статье показано, что можно сгенерировать 2 строки с одинаковым значением хеш-функции за меньшее время. Вы все еще не можете сгенерировать строку, которая приравнивается к конкретному хешу за разумное время. Между ними есть большая разница.

1 голос
/ 19 сентября 2008

Почти хорошая идея.

Хорошей идеей является хранение только хеша, который десятилетиями служил в мире паролей.

Добавление соли кажется справедливой идеей и действительно делает атаку грубой силой намного сложнее для атакующего. Но эта соль будет стоить вам много дополнительных усилий, когда вы действительно проверите, чтобы убедиться, что новый CC уникален: вам придется SHA-1 ваш новый номер CC N раз, где N - количество солей, которые у вас есть уже используется для всех CC, с которыми вы сравниваете. Если вы действительно выбираете хорошие случайные соли, вам придется делать хеш для каждой другой карты в вашей системе. Так что теперь вы делаете грубую силу. Поэтому я бы сказал, что это не масштабируемое решение.

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

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

1 голос
/ 19 сентября 2008

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

С эта статья ужасов кодирования :

Добавьте длинную уникальную случайную соль для каждого пароля, который вы храните. Основная идея (или одноразовый номер, если вы предпочитаете) состоит в том, чтобы сделать каждый пароль уникальным и достаточно длинным, чтобы атаки методом "грубой силы" были пустой тратой времени. Таким образом, пароль пользователя, вместо того, чтобы быть сохраненным как хэш «myspace1», в конечном итоге сохраняется как хэш из 128 символов случайной строки Unicode + «myspace1». Теперь вы полностью невосприимчивы к атакам радужного стола.

0 голосов
/ 14 сентября 2014

Если вы используете платежный процессор, такой как Stripe / Braintree, позвольте им выполнять «тяжелую работу».

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

  • Stripe возвращает fingerprint string - см. doc
  • Брейнтри возвращается unique_number_identifier string - см. Документ
0 голосов
/ 19 сентября 2008

Sha1 не работает здесь не проблема. Все это означает, что вычисление коллизий (2 набора данных с одинаковым sha1) возможно более легко, чем вы ожидаете. Это может быть проблемой для приема произвольных файлов, основанных на их sha1, но у него нет возможности для приложения внутреннего хеширования.

...