У меня есть процесс оформления заказа для корзины покупок, которая в данный момент хранит данные кредитной карты в сеансе для извлечения, как только пользователь завершает покупку. Процесс покупки настроен так, что пользователь вводит кредитную карту, просматривает страницу подтверждения, а затем завершает заказ. Действия по подтверждению и завершению являются единственными двумя действиями, для которых требуется доступ к данным кредитной карты, и для обеспечения безопасности все остальные действия должны быть отменены.
Если не считать отражения в базовом контроллере для проверки текущего действия, которое вызывает пользователь, я не могу придумать элегантного способа отбросить данные по запрещенным запросам. Кроме того, если пользователь не сможет сделать еще один запрос после ввода данных, он будет задерживаться в сеансе до тех пор, пока он не вернется на веб-сайт - всякий раз, когда это происходит. Одним из предложений, которое мне предложили, было шифрование данных в скрытом поле и использование билета 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;
}
}