Подтвердить что ты не робот

Хранение номеров кредитных карт на СЕЗОНЕ - пути вокруг него?

Мне хорошо известно о соблюдении PCI Compliance, поэтому не нужно разбираться в хранении номеров CC (и особенно CVV num) в нашей базе данных компании во время процесса оформления заказа.

Тем не менее, я хочу быть в безопасности, насколько это возможно, при обработке конфиденциальной информации о потребителях, и мне любопытно, как обойти номера CC с страницы на страницу БЕЗ использования переменных SESSION, если это вообще возможно.

Мой сайт построен таким образом:

  • Шаг 1) собрать кредитную карту информация от клиента - когда отзывы клиентов, информация сначала запускается через JS валидация, а затем запустить через PHP проверка, если все проходит, он перемещается к шагу 2.
  • Шаг 2) Информация отображается на страницу обзора для клиента обязательно подробности их предстоящих транзакции. Только первые 6 и последние 4 из CC показан на этой странице, но тип карты, и срок действия - полностью. Если он клики продолжаются,
  • Шаг 3) Информация отправляется другая php-страница, которая запускает один последний проверка, отправка информации через безопасный платежный шлюз и строка возвращается с подробностями.
  • Шаг 4) Если все хорошо и хорошо, потребительская информация (личная, а не CC) хранится в БД и перенаправляется на страницу завершения. Если что-то есть Плохо, ему сообщили и сказали перейдите на страницу обработки CC повторите попытку (максимум 3 раза).

Любые предложения?

ИЗМЕНИТЬ

Я получил очень хороший ответ на этот вопрос - большинство похоже согласны в следующем:

  • принятие POST-переменных после проверка выполняется
  • шифрование ccnum и cvv (не уверен вам разрешено хранить cvv в DB на всех, хотя)
  • Сохранение в временном БД
  • Доступ к БД сразу после "проверки" страница OK'd
  • расшифровать данные из базы данных
  • отправить информацию процессору
  • получить ответ
  • завершить DB

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

Я программирую в PHP и MySQL DB

EDIT # 2

Я столкнулся с Packet General, который кажется идеальным решением, но ДЕЙСТВИТЕЛЬНО не хочет платить за другую лицензию на программное обеспечение для достижения этой цели. http://www.packetgeneral.com/pcigeneralformysql.html

РЕДАКТИРОВАТЬ № 3 - Пример кода

Теперь я опубликовал некоторый пример кода, который я собрал, пытаясь понять шифрование/дешифрование/ключ и память, упомянутые в этом сообщении. Надеемся, что уже полезные вкладчики могут подтвердить, а другие могут использовать аналогичные функции. Ради длины я не буду вдаваться в методы проверки, используемые для собственно CC num.

Ввод формы

<form action="<?php $_SERVER['PHP_SELF']; ?>" method="POST">
<input type="text" name="CC" />
<input type="text" name="CVV" />
<input type="text" name="CardType" />
<input type="text" name="NameOnCard" />
<input type="submit" name="submit" value="submit" />
</form>

PHP Шифрование и сохранение данных

<?php

$ivs = mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($ivs,MCRYPT_RAND);
$key = "1234"; //not sure what best way to generate this is!
$_SESSION['key'] = $key;

$ccnum = $_POST['CC'];
$cvv = $_POST['CVV'];
$cctype = $_POST['CardType'];
$ccname = $_POST['NameOnCard'];

$enc_cc = mcrypt_encrypt(MCRYPT_DES, $key, $ccnum, MCRYPT_MODE_CBC, $iv);
$enc_cvv = mcrypt_encrypt(MCRYPT_DES, $key, $cvv, MCRYPT_MODE_CBC, $iv);
$enc_cctype = mcrypt_encrypt(MCRYPT_DES, $key, $cctype, MCRYPT_MODE_CBC, $iv);
$enc_ccname = mcrypt_encrypt(MCRYPT_DES, $key, $ccname, MCRYPT_MODE_CBC, $iv);


//if we want to change BIN info to HEXIDECIMAL
// bin2hex($enc_cc)

$conn = mysql_connect("localhost", "username", "password");
mysql_select_db("DBName",$conn);

$enc_cc = mysql_real_escape_string($enc_cc);
$enc_cvv = mysql_real_escape_string($enc_cvv);
$enc_cctype = mysql_real_escape_string($enc_cctype); 
$enc_ccname = mysql_real_escape_string($enc_ccname);

$sql = "INSERT INTO tablename VALUES ('$enc_cc', '$enc_cvv', '$enc_cctype', '$enc_ccname');

$result = mysql_query($sql, $conn) or die(mysql_error());
mysql_close($conn);

Header ("Location: review_page.php");

?>

PHP дешифрование данных и отправка на шлюз

    $conn = mysql_connect("localhost", "username", "password");
    mysql_select_db("DBName",$conn);

$result = mysql_query("SELECT * FROM tablename");

echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_ccnum, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_cvv, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_cctype, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_ccname, MCRYPT_MODE_CBC, $iv);

mysql_close($con);
?>

затем перейдите к передаче данных, только что отправленных в строке, и используйте их в представлении "Шлюз". Понятно?

4b9b3361

Ответ 1

Рассмотрите возможность изменения процесса оформления заказа, чтобы избавиться от необходимости хранить информацию о кредитной карте.

Страница 1: Пользователь вводит информацию о некредитной карточке, например, адрес доставки и платежный адрес Страница 2: Пользователь проверяет информацию о некредитной карточке, вводит информацию о кредитной карте и нажимает "Оплатить сейчас" (или "Изменить порядок", если они хотят изменить ситуацию)
Шаг 3: Информация отправляется через запрос $_POST на страницу SSL, которая завершает проверки на сервере, передает данные кредитной карты процессору и направляет пользователя на страницу успеха или ошибки на основе ответа.

Таким образом вы избегаете мутности технических проблем и проблем с соблюдением. Хранение данных кредитной карты в базе данных или в файле cookie даже на короткий период времени, даже если зашифровано, означает, что вы отвечаете за более высокий уровень соответствия PCI. Единственным компромиссом является то, что вы не сможете отобразить страницу "Просмотр заказа" с данными кредитной карты. И насколько большой компромисс заключается в том, что, если ваша страница "Заказ на просмотр" не может даже показать номер полной кредитной карты?

Ответ 2

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

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

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

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

Ответ 3

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

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

Поэтому я считаю, что лучшим подходом было бы отправить данные карты на платежный шлюз, как только они будут собраны. Многие платежные шлюзы позволят вам выполнить транзакцию типа "только в магазине", которая будет выполнять базовую проверку данных карты и сохранить номер карты на своем (уже совместимом с PCI) сервере и вместо этого вернуть вам идентификатор токена. Этот метод означает, что вы НЕ ДОЛЖНЫ хранить полный номер карты /cvv 2 в любом месте на своих серверах, а соблюдение PCI становится намного проще.

Позже в процессе проверки вы используете идентификатор токена, чтобы отправить авторизацию и расчет.

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

Ответ 4

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

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

EDIT: Просто подумал об этом:

  • Создайте случайный 128-битный ключ. Сохраните это в сеансе.
  • Шифровать данные с помощью ключа. Отправьте его клиенту в < input type = "hidden" >
  • При подтверждении, расшифруйте данные и отправьте транзакцию.

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

EDIT: И я забыл детали. Для всех этих схем (а не только для моих) вам также нужен MAC для предотвращения повторных атак (или Ева отвлекает Алису, изменяет корзину покупок и адрес выставления счетов и попадает на страницу подтверждения). В общем, вы хотите иметь MAC-адрес для всех данных транзакции (CC, CVV, идентификатор транзакции, сумма транзакции, адрес фактурирования...).

Ответ 5

Вы правы, использование сеансов очень небезопасно для хранения конфиденциальных данных, есть способы взломать сеансы с тем, что известно как:

Захват сеанса
Фиксация сеанса

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

Обратите внимание:

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

Вы можете найти этот, отражающий полезность:)

Ответ 6

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

Ответ 7

Есть другой способ, но для него требуется Ajax. Нет хранения номеров кредитных карт и страницы обзора.

Страница 1: Форма для хранения информации о доставке, биллинге и кредитной карте. Убедитесь, что "тело" страницы, включая форму, находится в DIV с уникальным идентификатором, чтобы вы могли ссылаться на него с помощью JavaScript.

Страница 2: Файл на сервере, который будет принимать запрос GET/POST с полями формы в нем и вернуть надлежащим образом отформатированную страницу "Обзор" по вашему вкусу.

Процесс оформления заказа:

  • Подтвердить форму.
  • Скопировать связанные поля кредитной карты в глобальные переменные JavaScript.
  • Прокрутите поля формы и постройте строку запроса/данных с полями формы (за исключением полей, связанных с кредитной картой).
  • Сделайте запрос Ajax на страницу "обзор", передав с ним строку запроса полей/значений формы. Отобразить на сервере и вернуться к функции Ajax вызова.
  • Возьмите предоставленную страницу обзора HTML, возвращенную из запроса Ajax, и замените содержимое в своем контейнере "DIV" (эффективно заменив форму и другие элементы на HTML-код обзора).
  • Используйте JavaScript, чтобы скопировать данные кредитной карты, хранящиеся в глобальных переменных JS, в соответствующее место на странице обзора. Вы также можете скопировать данные карты в скрытые поля формы для отправки, когда пользователь "завершает" заказ со страницы "Обзор".
  • Пользователь отправляет заказ с страницы обзора на сервер, выполняет проверку карты с помощью шлюза процессора, а затем либо размещает заказ, либо возвращается на страницу обработки ошибок, никогда не сохраняя данные о карте.
  • Я бы рекомендовал, чтобы функция "порядок места" выполняла полный HTTP-запрос (а не Ajax), чтобы перезагрузить браузер со страницей, на которой больше не хранятся данные карты в глобальных переменных JS.

Это немного взломанный, но когда он сделан правильно, он на 100% бесшовна для пользователя и позволяет вам осуществлять единую передачу данных карты без необходимости принимать риски при хранении временного БД и т.д.

Ответ 8

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

Ответ 9

Вот как я планирую это сделать - все по https, используя ssl, конечно.

Шаг 1. Пользователь вводит информацию CC и нажимает следующую кнопку. Информация CC немедленно сохраняется в DB процессора CC, а не в вашей собственной БД, иначе вы нарушите PCI Compliance. На этом CC фактически не взимается. Но вы должны получить уникальный идентификатор от процессора, идентифицирующий информацию CC. (если вы хотите сохранить уникальный идентификатор в своем db)

Шаг 2. На странице подтверждения извлеките информацию CC из процессора CC, используя уникальный идентификатор, который они вам предоставили. Мой процессор только позволит мне получить последние 4 номера CC в любом случае.

Шаг 3. После подтверждения покупки и нажмите кнопку "Купить сейчас", зарядите кредитную карту с помощью уникального идентификатора.

Шаг 4. Перенаправление на страницу с благодарностью, содержащую счет /reciept, который содержит только последние 4 цифры CC (конечно, вам не нужно отображать последние 4 из CC, но я думаю, что это приятно вещь, чтобы показать).

Ответ 10

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

Ответ 11

В какой-то момент в процессе обработки платежа (последняя часть шага 3) вам нужно будет зашифровать CС# (и CVC), чтобы отправить его в обработчик платежей (я полагаю)

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

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

Ответ 12

Нет необходимости в сеансах или базе данных для хранения информации.

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

Пока форма передается через HTTPS, данные зашифровываются автоматически, а бремя безопасности лежит на вашем поставщике сертификатов SSL.

Многие популярные сайты коммерции реализуют это. Например, OSCommerce.