Лучший способ предотвратить дублирование использования кредитных карт

17

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

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

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

Вы, ребята, видите недостатки в этом методе? Является ли это стандартным способом решения этой проблемы?

    
задан Lars A. Brekken 19.09.2008 в 17:54
источник

15 ответов

17

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

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

  

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

     

...

     

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

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

    
ответ дан Nick Johnson 19.09.2008 в 20:46
источник
10

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

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

Шаг 1:

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

Шаг 2:

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

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

    
ответ дан Wedge 19.09.2008 в 18:52
источник
5

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

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

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

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

Несмотря на то, что я считаю, что это решение way лучше, чем просто хранить несостоявшийся хэш номера CC, это не помешает очень мотивированному пирату (которому удается получить копию базы данных) разбить одну кредитную карту в среднем на 2-5 лет. Поэтому, если у вас есть 100k кредитных карт в вашей базе данных, и если у пирата есть lot процессора, он может каждый день восстанавливать несколько номеров кредитных карт!

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

Второе решение

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

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

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

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

    
ответ дан MiniQuark 12.08.2009 в 20:03
источник
3

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

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

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

    
ответ дан J.D. Fitz.Gerald 19.09.2008 в 18:43
источник
2

@Cory R. King

SHA 1 сам по себе не нарушается. В статье показано, что можно генерировать 2 строки, которые имеют одно и то же значение хеширования меньше, чем время грубой силы. Вы по-прежнему не можете генерировать строку, которая приравнивается к ХОРОШЕМУ КОНКРЕТНОМУ за разумное время. Между ними существует большая разница.     

ответ дан Kibbee 19.09.2008 в 18:13
источник
2

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

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

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

    
ответ дан TIMEX 11.08.2014 в 10:02
источник
1

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

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

  

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

    
ответ дан ine 19.09.2008 в 17:58
источник
1

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

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

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

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

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

    
ответ дан Jeff 19.09.2008 в 17:58
источник
0

Да, сравнение хэшей должно работать нормально в этом случае.

    
ответ дан Ben Hoffstein 19.09.2008 в 17:56
источник
0

Соленый хэш должен работать нормально. Наличие системы солей для пользователей должно быть достаточным для обеспечения безопасности.

    
ответ дан Chris Marasti-Georg 19.09.2008 в 17:57
источник
0

SHA1 не работает . Конечно, информации о том, что такое хорошая замена, мало информации. SHA2?

    
ответ дан Cory R. King 19.09.2008 в 18:02
источник
0

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

ответ дан Rob Allen 19.09.2008 в 18:08
источник
0

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

    
ответ дан Mitchel Sellers 19.09.2008 в 18:13
источник
0

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

    
ответ дан Martin Beckett 19.09.2008 в 18:13
источник
0

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

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

ответ дан Michael 14.09.2014 в 15:29
источник