ASP.NET MVC - Безопасное временное хранение данных кредитных карт - PullRequest
9 голосов
/ 22 декабря 2009

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

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

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


Возможно, кто-то может сказать мне, если это достаточный подход. Я установил в своей Корзине покупок, которая хранится в сеансе, уникальный идентификатор Guid, генерируемый при каждом обновлении объекта, и этот Guid используется в качестве ключа для шифрования и дешифрования данных кредитной карты, которые я сериализую с Rijndael алгоритм . Затем зашифрованные данные карты передаются пользователю в скрытом поле и десериализуются после нажатия кнопки «Завершить». Конечный результат - строка, похожая на эту:

VREZ%2bWRPsfxhNuOMVUBnWpE%2f0AaX4hPgppO4hHpCvvwt%2fMQu0hxqA%2fCJO%2faOEi%2bX3n9%2fP923mVestb7r8%2bjkSVZDVccd2AJzCr6ak7bbZg8%3d

public static string EncryptQueryString(object queryString, Guid encryptionKey)
{
    try
    {
        byte[] key = Encoding.UTF8.GetBytes(ShortGuid.Encode(encryptionKey).Truncate(16));//must be 16 chars
        var rijndael = new RijndaelManaged
                           {
                               BlockSize = 128,
                               IV = key,
                               KeySize = 128,
                               Key = key
                           };

        ICryptoTransform transform = rijndael.CreateEncryptor();

        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(queryString.ToString());

                cs.Write(buffer, 0, buffer.Length);
                cs.FlushFinalBlock();
                cs.Close();
            }
            ms.Close();
            return HttpUtility.UrlEncode(Convert.ToBase64String(ms.ToArray()));
        }
    }
    catch
    {
        return null;
    }
}

Ответы [ 3 ]

11 голосов
/ 22 декабря 2009

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

  1. Авторизация -> Семантика завершения.
  2. лексемизация

Авторизация позволяет зарезервировать назначенную сумму сбора в момент получения информации о платеже, а затем «Завершение» позволяет передать платеж в пакет платежей после подтверждения оплаты / заказа. Если заказ отменен, вам не нужно выдавать Завершение, и вы также можете попытаться удалить авторизацию.

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

Хранение фактической информации о кредитной карте любым способом, кроме передачи платы шлюзу / процессору, является плохой идеей. Помимо проблем защиты данных, это также поместит ваше приложение в область хранения информации о карте для PCI / PABP, что влечет за собой множество правил и положений, с которыми вы не захотите иметь дело в своем приложении. Я полагаю, что в следующем году также будет взиматься регулирующая плата за совместимые приложения, по общему мнению, 10 тыс. Долларов США. Все это, вероятно, не стоит проблем для вас или вашего клиента.

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

Класс SecureString (System.Security) @ MSDN

2 голосов
/ 22 декабря 2009

А как насчет использования TempData? Вам нужно будет поместить значение обратно в TempData между действиями подтверждения и завершения, но по крайней мере оно будет отбрасываться при каждом запросе. Обратите внимание, что TempData использует Session для хранения, поэтому он более не защищен во время хранения, но имеет функцию автоматического удаления. Я бы тоже не стал хранить номер на странице. Я подозреваю, что это нарушает правила PCI.

Другой альтернативой может быть сохранение информации о карте в базе данных. Если вы вообще храните это в своем приложении, вы, вероятно, уже в любом случае подчиняетесь правилам PCI. Хранение в БД облегчает задачу, так как вам нужно только указать идентификатор платежной карты в последующих запросах. Это может быть легко в скрытом поле.

0 голосов
/ 22 декабря 2009

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

Готов ли ваш клиент столкнуться с общими правилами Visa / MasterCard / AMC / Discover для обработки кредитных карт в режиме онлайн (PCI DSS)? Ваш клиент может в конечном итоге быть заблокирован крупными компаниями-эмитентами кредитных карт для осуществления операций с ними. В общем, это очень плохая идея - попробовать применить собственное решение для работы с кредитными картами в Интернете - это хуже, чем использовать собственный криптографический алгоритм, поскольку к клиенту могут быть применены серьезные штрафы (мелкий шрифт в их соглашении с продавцом). Настоящее решение PCI DSS требует десятков тысяч долларов на сертификацию и аудит, чтобы гарантировать, что оно обрабатывает данные кредитных карт по-настоящему безопасным способом - вот почему почти каждый использует существующий онлайн-процессор.

...