2008-09-19 3 views
17

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

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

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

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

ответ

0

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

0

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

+0

Согласен. Имейте в виду, что это делает регистрацию кредитной карты операцией O (n), где n - это существующее количество зарегистрированных карт. Плюс хеширование - довольно дорогостоящая операция. – Johan 2008-09-19 16:03:40

1

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

От this Coding Horror article:

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

+0

Да, но если вы используете различную случайную соль для каждого хэша, вам нужно попробовать каждую соль для нового значения, которое вы хотите сравнить. Используйте длинную случайную, но постоянную строку + срок годности. – 2008-09-19 16:02:19

+0

Если вы используете срок годности в соли, как она постоянна? – ine 2008-09-19 16:16:15

+0

Если они не используют словарь, который включает в себя срок годности, как соль. – 2011-11-28 15:30:07

1

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

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

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

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

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

+0

Ah - и если SHA-1 настолько дорога, что добавление этой соли фактически будет стоить хакерским годам, тогда это будет так дорого, что вы, вероятно, будете страдать, чтобы добавить к CC номер 10000. Но вы всегда можете просто протестировать его по сравнению с ожидаемым размером клиентской базы и посмотреть, не больно ли это. – Jeff 2008-09-19 16:29:48

+2

-1 Извините, но я действительно не согласен с этим ответом: вы не можете обрабатывать номера кредитных карт, такие как пароли, потому что люди могут выбирать сложные пароли, если необходимо (длинные, с буквами, цифрами и специальными символами), тогда как номера кредитных карт всего около 16 цифр, а половина из них можно легко угадать (первые 7 являются отраслевыми стандартами (см. ответ Ник Джонсона), а последние 4 хранятся в базе данных в соответствии с вопросом (и это обычная практика). действительно делайте * не * храните «только хэш». Вместо этого следуйте за ответом Клина или моим. – MiniQuark 2009-08-12 16:55:49

0

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

0

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

0

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

2

@Cory R. King

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

0

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

3

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

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

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

10

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

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

Шаг 1:

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

Шаг 2:

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

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

17

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

По случайному совпадению, ища что-то дают алгоритм хеширования тесты, я нашел this article about storing credit card hashes, который говорит:

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

...

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

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

5

Do не магазин простой SHA-1 из номера кредитной карты, это будет путь к легко взломать (тем более, что последние 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 лет. Так что если у вас есть 100k кредитных карт в вашей базе данных, и если у пирата есть лот процессора, то он может восстановить несколько номеров кредитных карт каждый день!

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

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

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

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

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

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

2

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

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

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

0

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

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

  • нашивки возвращает fingerprint строку - см doc
  • Брэйнтри возвращает unique_number_identifier string - см doc
Смежные вопросы