ASP.NET MVC - 信用卡数据的安全临时存储

时间:2022-06-01 14:15:08

I have a checkout process for a shopping cart that is currently storing credit card data in the session for retrieval once the user finalizes the purchase. The purchase process is set up such that the user inputs the credit card, views a confirmation page, and then finalizes the order. The confirmation and finalization actions are the only two actions that need access to the credit card data and to be safe all other actions should discard it.

我有一个购物车的结账流程,当前用户在完成购买后,会在会话中存储信用卡数据以供检索。设置购买过程,使得用户输入信用卡,查看确认页面,然后完成订单。确认和最终确定操作是需要访问信用卡数据的唯一两个操作,并且安全所有其他操作都应该丢弃它。

Short of doing reflection in a base controller to check the current action the user is calling, I cannot think of an elegant way to discard the data on the disallowed requests. Additionally, if the user fails to make another request after entering the data it will linger in the session until they come back to the website- whenever that happens. One suggestion I was offered was encrypting the data into a hidden field and relying on the SSL ticket to prevent caching the markup. This seems like a fairly safe approach, but I don't much like the idea of placing the credit card data in a user-accessible location encrypted or not. Storing in the database is out because the client does not want credit card data saved.

如果没有在基本控制器中进行反射来检查用户正在调用的当前操作,我想不出一种优雅的方法来丢弃不允许的请求上的数据。此外,如果用户在输入数据后未能提出另一个请求,它将在会话中停留,直到他们回到网站 - 每当发生这种情况时。我提出的一个建议是将数据加密到隐藏字段并依赖SSL票证来防止缓存标记。这似乎是一种相当安全的方法,但我不太喜欢将信用卡数据放在用户可访问的位置加密或不加密的想法。存储在数据库中是因为客户端不希望保存信用卡数据。

What is the ideal approach to temporarily persisting sensitive data like credit card information across more than one page request?

在多个页面请求中临时保存信用卡信息等敏感数据的理想方法是什么?


Perhaps someone can tell me if this is a sufficient approach. I have set my Shopping Cart which is stored in the session to have a unique Guid generated every time the object is newed and that Guid is used as a key to encrypt and decrypt the credit card data which i am serializing with the Rijndael algorithm. The encrypted card data is then passed to the user in a hidden field and deserialized after finalize is clicked. The end result is a string much like this:

也许有人可以告诉我这是否是一个充分的方法。我已经设置了存储在会话中的购物车,每次创建对象时都会生成一个唯一的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 个解决方案

#1


11  

The best way to handle this scenario is to use a payment service that supports two things:

处理此方案的最佳方法是使用支持两件事的支付服务:

  1. Authorization -> Completion semantics.
  2. 授权 - >完成语义。
  3. Tokenization
  4. 符号化

Authorization allows you to reserve the designated charge amount at the time the payment information is received, and then Completion allows you to commit the charge to the payment batch once the payment/order is confirmed. If the order is canceled, you don't have to issue a Completion and you can also attempt to delete the authorization as well.

授权允许您在收到付款信息时保留指定的费用金额,然后完成后,您可以在确认付款/订单后将费用提交到付款批次。如果订单被取消,您不必签发“完成”,也可以尝试删除授权。

Regarding tokenization, most gateways that support the aforementioned method of handling payments will return a token, typically a numeric id, for the pending transaction. The token may then be handled however you wish, as it has no value to anyone without access to your authentication credentials at the gateway. This transfers the burden of safety to the gateway as well.

关于标记化,支持上述处理支付方法的大多数网关将为未决事务返回令牌,通常是数字ID。然后可以根据需要处理令牌,因为它对没有访问网关的身份验证凭据的任何人都没有价值。这也将安全负担转移到网关。

Storing the actual credit card information in any way other than relaying a charge to a gateway/processor is a bad idea. Beyond the problems of securing the data, this will also put your application into card information storage scope for PCI/PABP, which entails a lot of rules and regulations that you won't want to deal with in your application. I believe there is also a regulatory fee that will be imposed in the coming year for compliant applications, reputedly $10k USD. All of this is likely not worth the trouble to you or your client.

以除了将费用中继到网关/处理器之外的任何方式存储实际的信用卡信息是一个坏主意。除了保护数据的问题之外,这还将使您的应用程序进入PCI / PABP的卡信息存储范围,这需要您在应用程序中不需要处理的许多规则和规定。我相信,对于合规申请,明年还将收取监管费,据称是1万美元。所有这些对您或您的客户来说可能都不值得。

Last, during intermediate processing (in-page/event/route handlers), you can use a SecureString to hold the contents of the data until you no longer need them.

最后,在中间处理(页内/事件/路由处理程序)期间,您可以使用SecureString来保存数据的内容,直到您不再需要它们为止。

SecureString class (System.Security) @ MSDN

SecureString类(System.Security)@ MSDN

#2


2  

What about using TempData? You'd need to put the value back into TempData between the confirmation and finalization actions, but at least it will be discarded with each request. Note that TempData uses the Session for storage so it's no more secure while it's being stored, but it does have the automatic removal feature. I, too, would resist storing the number on the page. I suspect that this violates the PCI rules.

那么使用TempData呢?您需要在确认和终止操作之间将值重新放回TempData,但至少每次请求都会丢弃它。请注意,TempData使用Session进行存储,因此在存储时不会更安全,但它确实具有自动删除功能。我也不会在页面上存储该号码。我怀疑这违反了PCI规则。

Another alternative would be to store the card info in a database. If you keep it at all in your application you're probably already subject to the PCI rules anyway. Storing it in the DB makes it easier as then you only need to put the billing card id in subsequent requests. This could easily be in a hidden field.

另一种选择是将卡信息存储在数据库中。如果您在应用程序中完全保留它,那么您可能已经受到PCI规则的约束。将其存储在数据库中会使其变得更容易,因此您只需将计费卡ID放入后续请求中即可。这可能很容易在一个隐藏的领域。

#3


0  

What country is this based in and what credit card companies are involved? The entire approach of actually sending full credit card numbers back to the client (in whatever form) makes this sound like you have not dealt with professional credit card handling (please don't take that as an insult).

这个基于什么国家和哪些信用卡公司参与?实际上将完整的信用卡号码发送回客户端(无论采用何种形式)的整个方法使得这听起来像是您没有处理专业信用卡处理(请不要将其视为侮辱)。

Is your client willing to run afoul of Visa/MasterCard/AMC/Discover's collective rules for online credit card processing (PCI DSS)? Your client could end being barred by the major credit card companies from doing transactions with them. In general it is a very bad idea to try rolling your own online credit card handling solution - it's worse then rolling your own cryptographic algorithm, as there can be serious fines applied to your client (fine print in their merchant agreement). A true PCI DSS solution requires tens of thousands of dollars in certifications and audits to ensure it handles credit card data in a truly secure fashion - this is why almost everyone uses an existing online processor.

您的客户是否愿意违反Visa / MasterCard / AMC / Discover的在线信用卡处理(PCI DSS)的集体规则?您的客户可能会被主要信用卡公司禁止与他们进行交易。一般来说,尝试滚动自己的在线信用卡处理解决方案是一个非常糟糕的主意 - 它比滚动自己的加密算法更糟糕,因为可能会对您的客户进行严重罚款(商家协议中的细则)。真正的PCI DSS解决方案需要数万美元的认证和审核,以确保以真正安全的方式处理信用卡数据 - 这就是为什么几乎每个人都使用现有的在线处理器。

#1


11  

The best way to handle this scenario is to use a payment service that supports two things:

处理此方案的最佳方法是使用支持两件事的支付服务:

  1. Authorization -> Completion semantics.
  2. 授权 - >完成语义。
  3. Tokenization
  4. 符号化

Authorization allows you to reserve the designated charge amount at the time the payment information is received, and then Completion allows you to commit the charge to the payment batch once the payment/order is confirmed. If the order is canceled, you don't have to issue a Completion and you can also attempt to delete the authorization as well.

授权允许您在收到付款信息时保留指定的费用金额,然后完成后,您可以在确认付款/订单后将费用提交到付款批次。如果订单被取消,您不必签发“完成”,也可以尝试删除授权。

Regarding tokenization, most gateways that support the aforementioned method of handling payments will return a token, typically a numeric id, for the pending transaction. The token may then be handled however you wish, as it has no value to anyone without access to your authentication credentials at the gateway. This transfers the burden of safety to the gateway as well.

关于标记化,支持上述处理支付方法的大多数网关将为未决事务返回令牌,通常是数字ID。然后可以根据需要处理令牌,因为它对没有访问网关的身份验证凭据的任何人都没有价值。这也将安全负担转移到网关。

Storing the actual credit card information in any way other than relaying a charge to a gateway/processor is a bad idea. Beyond the problems of securing the data, this will also put your application into card information storage scope for PCI/PABP, which entails a lot of rules and regulations that you won't want to deal with in your application. I believe there is also a regulatory fee that will be imposed in the coming year for compliant applications, reputedly $10k USD. All of this is likely not worth the trouble to you or your client.

以除了将费用中继到网关/处理器之外的任何方式存储实际的信用卡信息是一个坏主意。除了保护数据的问题之外,这还将使您的应用程序进入PCI / PABP的卡信息存储范围,这需要您在应用程序中不需要处理的许多规则和规定。我相信,对于合规申请,明年还将收取监管费,据称是1万美元。所有这些对您或您的客户来说可能都不值得。

Last, during intermediate processing (in-page/event/route handlers), you can use a SecureString to hold the contents of the data until you no longer need them.

最后,在中间处理(页内/事件/路由处理程序)期间,您可以使用SecureString来保存数据的内容,直到您不再需要它们为止。

SecureString class (System.Security) @ MSDN

SecureString类(System.Security)@ MSDN

#2


2  

What about using TempData? You'd need to put the value back into TempData between the confirmation and finalization actions, but at least it will be discarded with each request. Note that TempData uses the Session for storage so it's no more secure while it's being stored, but it does have the automatic removal feature. I, too, would resist storing the number on the page. I suspect that this violates the PCI rules.

那么使用TempData呢?您需要在确认和终止操作之间将值重新放回TempData,但至少每次请求都会丢弃它。请注意,TempData使用Session进行存储,因此在存储时不会更安全,但它确实具有自动删除功能。我也不会在页面上存储该号码。我怀疑这违反了PCI规则。

Another alternative would be to store the card info in a database. If you keep it at all in your application you're probably already subject to the PCI rules anyway. Storing it in the DB makes it easier as then you only need to put the billing card id in subsequent requests. This could easily be in a hidden field.

另一种选择是将卡信息存储在数据库中。如果您在应用程序中完全保留它,那么您可能已经受到PCI规则的约束。将其存储在数据库中会使其变得更容易,因此您只需将计费卡ID放入后续请求中即可。这可能很容易在一个隐藏的领域。

#3


0  

What country is this based in and what credit card companies are involved? The entire approach of actually sending full credit card numbers back to the client (in whatever form) makes this sound like you have not dealt with professional credit card handling (please don't take that as an insult).

这个基于什么国家和哪些信用卡公司参与?实际上将完整的信用卡号码发送回客户端(无论采用何种形式)的整个方法使得这听起来像是您没有处理专业信用卡处理(请不要将其视为侮辱)。

Is your client willing to run afoul of Visa/MasterCard/AMC/Discover's collective rules for online credit card processing (PCI DSS)? Your client could end being barred by the major credit card companies from doing transactions with them. In general it is a very bad idea to try rolling your own online credit card handling solution - it's worse then rolling your own cryptographic algorithm, as there can be serious fines applied to your client (fine print in their merchant agreement). A true PCI DSS solution requires tens of thousands of dollars in certifications and audits to ensure it handles credit card data in a truly secure fashion - this is why almost everyone uses an existing online processor.

您的客户是否愿意违反Visa / MasterCard / AMC / Discover的在线信用卡处理(PCI DSS)的集体规则?您的客户可能会被主要信用卡公司禁止与他们进行交易。一般来说,尝试滚动自己的在线信用卡处理解决方案是一个非常糟糕的主意 - 它比滚动自己的加密算法更糟糕,因为可能会对您的客户进行严重罚款(商家协议中的细则)。真正的PCI DSS解决方案需要数万美元的认证和审核,以确保以真正安全的方式处理信用卡数据 - 这就是为什么几乎每个人都使用现有的在线处理器。