Хранение данных кредитной карты - PullRequest
46 голосов
/ 16 октября 2008

У меня есть деловое требование, которое вынуждает меня хранить полные данные кредитной карты клиента (номер, имя, срок действия, CVV2) в течение короткого периода времени.

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

Я не могу это изменить. Существующая система хранит данные кредитной карты в виде открытого текста, и в новой системе, которую я собираюсь заменить, я явно не собираюсь повторить это!

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

Среда: C #, WinForms, SQL-Server.

Ответы [ 10 ]

47 голосов
/ 16 октября 2008

В основном избегайте ответственности за сохранение данных CC на своей стороне, однако я могу предположить, что вы используете стороннюю службу для выполнения транзакций, таких как PayPal / Verisign или что-то еще, большинство из них имеют API, которые позволяют вам чтобы сохранить учетные данные CC на их стороне, и они возвращают вам ключ, который вы затем сможете использовать позже для завершения или инициирования транзакций, поэтому они позаботятся о сложной части, в то время как все, что вам нужно сделать, это сохранить этот ключ строки в вашем DB.

13 голосов
/ 16 октября 2008

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

12 голосов
/ 16 октября 2008

Андрей, тебе нужно понять PCI-DSS , задача не из легких. Лично я нахожу это крайне расплывчатым, но вот что я понимаю.

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

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

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

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

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

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

8 голосов
/ 16 октября 2008

Если вы просто хотите сохранить строку в памяти в течение короткого периода времени, вы можете взглянуть на System.Security.SecureString .

Взято из этого ответа :

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

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

В конце примера SecureString преобразуется в обычную управляемую строку, что снова делает ее уязвимой (обязательно используйте шаблон try-catch-finally, чтобы обнулить строку после того, как вы поработаете с ней). SecureString используется для уменьшения площади атаки, ограничивая количество копий, которые собирает сборщик мусора, и уменьшая вероятность записи в файл подкачки.

// Make a SecureString
SecureString sPassphrase = new SecureString();
Console.WriteLine("Please enter your passphrase");
ConsoleKeyInfo input = Console.ReadKey(true);
while (input.Key != ConsoleKey.Enter)
{
   sPassphrase.AppendChar(input.KeyChar);
   Console.Write('*');
   input = Console.ReadKey(true);
}
sPassphrase.MakeReadOnly();

// Recover plaintext from a SecureString
// Marshal is in the System.Runtime.InteropServices namespace
try {
   IntPtr ptrPassphrase = Marshal.SecureStringToBSTR(sPassphrase);
   string uPassphrase = Marshal.PtrToStringUni(ptrPassphrase);
   // ... use the string ...
}
catch {
   // error handling
} 
finally {
   Marshal.ZeroFreeBSTR(ptrPassphrase);
}
8 голосов
/ 16 октября 2008

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

Сказав это, посмотрите на шифрование на уровне ячейки, доступное в SQL Server 2005 и выше. По совпадению :) Недавно я представил презентацию с примерами T-SQL по шифрованию с SQL Server 2005/2008, доступную здесь: http://moss.bennettadelson.com/Lists/Events/Attachments/9/June2008.zip (расположение ссылки обновлено 23 декабря 2008 г.)

6 голосов
/ 16 октября 2008

Где-то около 30000 долларов стоит быть должным образом податливым и иметь возможность делать подобные вещи. Вам лучше использовать сторонний платежный сервис. Лично я рекомендую Element Express, и у них есть «размещенное» решение, которое обходит соответствие PCI-DSS PAPDB. Я должен был преобразовать это для своих собственных приложений, даже для автомата Point of Sale !!! Это большая боль, но мы маленькая компания.

http://www.elementps.com/software-providers/our-security-edge/hosted-payments/PA-DSS-Certification-vs-Elements-Hosted-Payments/

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

Edit:

Кроме того, если вы решите сохранить информацию о кредитной карте, вам определенно необходимо рассмотреть формы шифрования, которые вы собираетесь использовать. Симметричный? Асимметричный?

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

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

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

Есть много вещей, чтобы принять во внимание.

Последнее примечание. Используйте платежный шлюз (Element Express, Authorize.NET, Paypal и т. Д.) И не храните информацию о кредитной карте локально. : P

Вот ссылка на использование асимметричного шифрования X509 в C #: http://www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html

5 голосов
/ 16 октября 2008

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

4 голосов
/ 26 сентября 2012

Рассмотрим ваши т логи!

Если вы объясните своему клиенту все последствия (и требования по исправлению, если они будут обнаружены в результате несоответствия), то поверьте мне, ваши «бизнес-требования» очень быстро изменятся.

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

Если в ваших журналах транзакций может быть указан номер кредитной карты в открытом виде, значит, вы не соблюдаете требования и должны предусмотреть бюджет судебного аудита на вашем сайте от 10 000 до 50 000 долларов, если вас поймают. Бюджет для собственного адвоката на случай, если ваш клиент подаст на вас в суд, потому что вы должны были знать все это.

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

И даже нет поля или столбца в вашей базе данных для CVV - зашифрованного или нет - этот судебный аудит покажет это (как и журналы), и тогда ваш клиент окажется в БОЛЬШИХ, БОЛЬШИХ проблемах. Они заплатят штраф и могут потерять способность принимать кредитные карты. Ваш адвокат будет очень счастлив.

4 голосов
/ 11 мая 2010

Давайте посмотрим на требование немного по-другому. В настоящее время это выглядит так:

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

ППЛ склонны так думать и запрашивать функции таким образом. Теперь я думаю, что ваше требование более удобно описать следующим образом:

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

Так что нет явного требования для хранения чего-либо (на вашей стороне), не так ли? Это только подразумевается

Платежные системы могут предоставлять программные API для вашего торгового счета и возможность повторной авторизации при отклоненной попытке. я думаю, что @bashmohandes ускользнул от этого раньше

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

Сценарий 1: Предполагая, что все, что я сказал, верно

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

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

Сценарий 2: Предполагая, что я совершенно не прав, но с юридической точки зрения, это хранилище СС - это нормально

Таким образом, вы должны временно хранить эти данные где-то. Я советую:

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

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

Сценарий 1 был бы хорош. Не так ли?

0 голосов
/ 07 ноября 2008

У меня есть запись в блоге, которая касается именно этой ситуации хранения конфиденциальных данных в базе данных. В блоге используется класс String Encryptor, который я создал с использованием алгоритма Triple DES, но вы можете подключить свой собственный, если хотите.

В блоге содержится видео и исходный код, который был использован. Вы можете проверить это в http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-in-nhibernateactive-record-video.html. Я думаю, что это определенно решит вашу проблему.

...