С вопросами безопасности все ответы лежат на континууме от наиболее безопасных до наиболее удобных . Я дам вам два ответа, один из которых очень безопасный, а другой очень удобный. Учитывая это и объяснение каждого из них, вы можете выбрать лучшее решение для вашей системы.
Вы заявили, что ваша цель состояла в том, чтобы сохранить это значение вместо действительной кредитной карты, чтобы впоследствии вы могли узнать, будет ли снова использоваться тот же номер кредитной карты. Это означает, что он должен содержать только номер кредитной карты и, возможно, единую соль. Включение CCV, даты истечения срока действия, имени и т. Д. Сделало бы его бесполезным, поскольку его значение могло бы отличаться при одном и том же номере кредитной карты. Поэтому мы предполагаем, что вы дополняете все номера своих кредитных карт одним и тем же солт-значением, которое останется единообразным для всех записей.
Удобное решение заключается в использовании FNV (как предложили Zebrabox и Ник). Это даст 32-битное число, которое будет быстро индексироваться для поиска. Недостатком, конечно, является то, что он допускает не более 4 миллиардов различных чисел, и на практике вызовет столкновения гораздо быстрее, чем это. Поскольку у него такой высокий уровень столкновений, атака грубой силой, вероятно, даст достаточно неверных результатов, чтобы сделать ее малопригодной.
Безопасное решение заключается в использовании хэш-функции SHA (чем больше, тем лучше), но с несколькими итерациями. Я бы предложил где-то порядка 10000. Да, я знаю, 10 000 итераций - это много, и это займет некоторое время, но когда дело доходит до силы против грубой силы, скорость атаки противника. Если вы хотите быть в безопасности, то вы хотите, чтобы это было МЕДЛЕННО. SHA разработан так, чтобы не было коллизий при любом размере ввода. Если обнаружено столкновение, то хеш считается более нежизнеспособным. AFAIK семья SHA-2 все еще жизнеспособна.
Теперь, если вам нужно решение, которое безопасное и быстрое для поиска в БД, тогда я бы предложил использовать безопасное решение (SHA-2 x 10K) и затем сохранить полный хеш в одном столбце. и затем возьмите первые 32 бита и сохраните их в другом столбце с индексом во втором столбце. Сначала выполните поиск 32-битного значения. Если это не дает совпадений, то у вас нет совпадений. Если оно дает совпадение, то вы можете сравнить полное значение SHA и посмотреть, совпадает ли оно. Это означает, что вы выполняете полное двоичное сравнение (хеши на самом деле являются двоичными, но представлены только в виде строк для удобного чтения человеком и для передачи в текстовых протоколах) на гораздо меньшем множестве.
Если вы действительно беспокоитесь о скорости, то можете уменьшить количество итераций. Честно говоря, это будет все еще быстро даже с 1000 итерациями. Вам нужно будет сделать несколько реалистичных суждений о том, насколько большой вы ожидаете получить базу данных, и о других факторах (скорость обмена данными, отклик оборудования, нагрузка и т. Д.), Которые могут повлиять на продолжительность. Вы можете обнаружить, что вы оптимизировали самую быструю точку в процессе, что практически не повлияет на результат.
Кроме того, я бы порекомендовал вам тест поиск полного хеша по сравнению с 32-битным подмножеством. Большинство современных систем баз данных являются довольно быстрыми и содержат ряд оптимизаций и часто оптимизируют для нас, делая вещи просто easy . Когда мы пытаемся стать умными, мы иногда просто замедляем это. Что это за цитата о преждевременной оптимизации? , ,