Хранение номеров кредитных карт в сеансе-пути вокруг него?

Я хорошо осведомлен о соответствии PCI, поэтому не нужно earful о хранении номеров CC (и особенно CVV nums) в нашей базе данных компании во время процесса проверки.

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

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

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

какие предложения?

редактировать

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

  1. принимая переменные POST после проверка выполняется
  2. шифрование ccnum и cvv (не уверен вам разрешено хранить cvv в DB вообще хоть)
  3. хранение во временной БД
  4. доступ к БД сразу после "обзора" страницы хорошо бы
  5. расшифровать детали из DB
  6. отправить информацию процессор
  7. получите ответ
  8. завершить DB

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

я программирую на PHP и MySQL DB

EDIT #2

я наткнулся на пакет General, который кажется идеальным решением, но на самом деле не хочу платить за другое программное обеспечение лицензия на достижение этой цели. http://www.packetgeneral.com/pcigeneralformysql.html

EDIT #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 расшифровка данных и отправка в gateway

    $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);
?>

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

13 ответов


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

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

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


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

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

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

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


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

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

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

позже в процессе оформления заказа вы используете идентификатор токена для отправки авторизации и сопоставления.

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


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

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

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

  1. создать случайный 128-битный ключ. Сохраните это в сеансе.
  2. зашифровать данные с помощью ключа. Отправьте его в клиент в
  3. при подтверждении расшифруйте данные и отправьте транзакцию.

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

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


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

сеанса
фиксация сессии

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

внимание:

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

вы можете найти этой рефлективно полезно, как хорошо :)


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


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

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

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

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

  1. проверка формы.
  2. скопируйте поля, связанные с кредитной картой, в глобальные переменные JavaScript.
  3. цикл через поля формы и построить строку запроса / данных с полями формы (за исключением полей, связанных с кредитной картой)
  4. сделайте запрос Ajax на страницу" обзор", передав с ней строку запроса поля/значений формы. Визуализация на сервере и возврат к вызову функции Ajax.
  5. принять оказанные HTML review страница, возвращенная из Ajax запроса и заменить содержимое в контейнере " DIV " с ним (эффективно заменяя форму и другие элементы с обзором HTML).
  6. используйте JavaScript для копирования данных кредитной карты, хранящихся в глобальных переменных JS, в соответствующее место на странице обзора. Вы также можете скопировать данные карты в скрытые поля формы для отправки, когда пользователь "завершит" заказ со страницы "Обзор".
  7. пользователь отправляет заказ со страницы обзора на сервер, выполнение проверки карты со шлюзом процессора, а затем либо размещение заказа, либо возврат на страницу обработки ошибок, никогда не сохранив данные карты.
  8. Я бы рекомендовал, чтобы функция "разместить заказ" выполняла полный HTTP-запрос (а не Ajax), чтобы перезагрузить браузер со страницей, которая больше не имеет данных карты, хранящихся в глобальных переменных JS.

Это немного взломать, но когда все сделано правильно, это 100% бесшовные для пользователя и позволяет вам одиночную передачу данных по карточки без потребности принять риски с хранить DB temp, etc.


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


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

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

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

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

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


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


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

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

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


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

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

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

многие популярные сайты это реализовать. Например, OSCommerce.


Использование Токенизации. Его полностью PCI DSS complient.

больше может быть fouhd здесь, https://www.pcisecuritystandards.org/documents/Tokenization_Guidelines_Info_Supplement.pdf