C# 存储信用卡详细信息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/206438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:01:17  来源:igfitidea点击:

Storing credit card details

c#securityencryptioncredit-cardpci-dss

提问by Andrew

I have a business requirement that forces me to store a customer's full credit card details (number, name, expiry date, CVV2) for a short period of time.

我有一个业务需求,迫使我在短时间内存储客户的完整信用卡详细信息(号码、姓名、到期日期、CVV2)。

Rationale: If a customer calls to order a product and their credit card is declined on the spot you are likely to lose the sale. If you take their details, thank them for the transaction and then find that the card is declined, you can phone them back and they are more likely to find another way of paying for the product. If the credit card is accepted you clear the details from the order.

理由:如果客户打电话订购产品,而他们的信用卡当场被拒绝,您很可能会失去销售机会。如果你记录了他们的详细信息,感谢他们的交易,然后发现卡被拒绝了,你可以给他们回电话,他们更有可能找到另一种支付产品的方式。如果接受信用卡,您将从订单中清除详细信息。

I cannot change this. The existing system stores the credit card details in clear text, and in the new system I am building to replace this I am clearly notgoing to replicate this!

我无法改变这一点。现有系统以明文形式存储信用卡详细信息,而在我正在构建以替换它的新系统中,我显然不会复制它!

My question, then, is how I can securely store a credit card for a short period of time. I obviously want some kind of encryption, but what's the best way to do this?

那么,我的问题是如何在短时间内安全地存储信用卡。我显然想要某种加密,但最好的方法是什么?

Environment: C#, WinForms, SQL-Server.

环境:C#、WinForms、SQL-Server。

回答by bashmohandes

Basically avoid by all means taking the responsiblity to save the CC details on your side, however I can assume you are using a thirdparty service to do your transaction such as PayPal/Verisign or whatever, most of them have API's that enables you to save CC credentials at their side, and they give you back a key that you can then use later to complete or initiate transactions, so they take care of the hard part, while all what you have to do is store this string key in your DB.

基本上尽量避免承担保存 CC 详细信息的责任,但是我可以假设您正在使用第三方服务来进行交易,例如 PayPal/Verisign 或其他任何服务,它们中的大多数都有 API 可以让您保存 CC凭据在他们身边,他们会给您一个密钥,您可以稍后使用该密钥来完成或启动事务,因此他们会处理困难的部分,而您所要做的就是将此字符串密钥存储在您的数据库中。

回答by Corbin March

Agreed that you should avoid storing the data if you can. But maybe you arethat third party? If so, get familiar with PCI standards. Look around a bit on the site and you'll find the security measures you are requiredto implement.

同意如果可以,您应该避免存储数据。但也许你就是那个第三方?如果是这样,请熟悉PCI 标准。在站点上稍微浏览一下,您会发现需要实施的安全措施。

回答by Joe Kuemerle

If you are going to store credit card information you really need to be PCI compliant or you're just asking for trouble.

如果您要存储信用卡信息,您确实需要符合 PCI 标准,否则您只是在自找麻烦。

Having said that look at the cell level encryption available in SQL Server 2005 and above. Coincidentally :) I have recently given a presentation with T-SQL samples on encryption with SQL Server 2005/2008 available here: http://moss.bennettadelson.com/Lists/Events/Attachments/9/June2008.zip(Link location updated December 23, 2008)

话虽如此,请查看 SQL Server 2005 及更高版本中可用的单元级加密。巧合的是 :) 我最近做了一个关于使用 SQL Server 2005/2008 进行加密的 T-SQL 示例的演示文稿:http: //moss.bennettadelson.com/Lists/Events/Attachments/9/June2008.zip(链接位置已更新2008 年 12 月 23 日)

回答by Cade Roux

I don't believe it's actually illegal to store CVV info (in the sense that it's against any law), but it does violate Payment Card Industry rules, and they could impose any number of different sanctions. So, your requirements could actually result in you not being able to accept credit cards ;-(

我不认为存储 CVV 信息实际上是非法的(从某种意义上说它违反任何法律),但它确实违反了支付卡行业规则,并且他们可以施加任何数量的不同制裁。因此,您的要求实际上可能会导致您无法接受信用卡;-(

回答by Flory

Andrew, you need to understand the PCI-DSS, no small task. Personally, I find it extremely vague but here is what I understand.

安德鲁,您需要了解PCI-DSS,这不是一件小事。就个人而言,我觉得它非常模糊,但这是我的理解。

First off, from the scenario you describe I would attempt to authorize the card for the full amount and then if that failed I would store the customer's information (but not the cardholder data) so someone could contact the user. Where I use to work some of our customers would only charge $1.00 and then void the transaction immediately, just to make sure the card was valid. They would then process all orders manually.

首先,根据您描述的情况,我会尝试对卡进行全额授权,然后如果失败,我将存储客户的信息(但不是持卡人数据),以便有人可以联系用户。我以前工作的地方,我们的一些客户只收取 1.00 美元,然后立即取消交易,以确保卡有效。然后他们将手动处理所有订单。

Where you will need to store the number is on a successful authorization. The only number you need then is the credit card number and the transaction code (at least with every gateway I have ever worked with).

您需要将号码存储在成功授权的位置。您唯一需要的数字是信用卡号和交易代码(至少对于我曾经使用过的每个网关)。

The standard, last time I looked at it, is not specific on encryption algorithms but instead makes it clear it should be currently unbreakable encryption.

上次我查看该标准时,该标准并未具体针对加密算法,而是明确指出它目前应该是不可破解的加密。

Now, one thing you cannot do is store the CCV subsequent to authorization. My understanding is that you can store it prior to authorization but I could never get anyone that would put that in writing. Basically, you authorize the card, you better wipe it.

现在,您不能做的一件事是在授权之后存储 CCV。我的理解是您可以在授权之前存储它,但我永远找不到任何人会写下来。基本上,你授权卡,你最好擦一下。

And it is not illegal at this point but if you get nailed they will bring the hammer down on you. They have within their authority to level heavy fines against you, but it seems like what they usually do is put you in remediation. If you don't comply I don't know what happens because everyone I have heard this happening to complied. But then they really go up your booty with a microscope.

这在这一点上并不违法,但如果你被钉死,他们会把锤子砸在你身上。他们有权对你处以巨额罚款,但他们通常所做的似乎是让你接受补救。如果你不遵守,我不知道会发生什么,因为我听说过的每个人都遵守了。但后来他们真的用显微镜放大了你的战利品。

Ultimately, I believe their only stick they really have is to prevent you from accepting credit cards. Most merchants I have worked with were scared to death of exactly that.

最终,我相信他们真正拥有的唯一方法是阻止您接受信用卡。与我合作过的大多数商人都对此感到害怕。

回答by sallen

If you just want to store the string for a short period of time in memory, you can take a look at System.Security.SecureString.

如果您只想在内存中短时间存储字符串,您可以查看System.Security.SecureString

Taken from this answer:

取自这个答案

SecureString values are stored encrypted (obfuscated, rather), but most importantly, they are never swapped to disk and can be disposed of immediately when you're done with them.

They're tricky to use because you can only build them one character at a time (to encourage you to build them by capturing keystrokes as the user types their password), and require three lines of code to recover and then wipe their plain text, but when used properly they can make a program more secure by avoiding the virtual-memory vulnerability.

At the end of the example the SecureString is converted into a regular managed string, which makes it vulnerable again (be sure to use the try-catch-finally pattern to Zero the string after you're done with it). SecureString's use is in reducing the surface-area of attack by limiting the number of copies the Garbage Collector will make of the value, and reducing the likelihood of being written to the swap file.

SecureString 值以加密方式存储(而是经过混淆处理),但最重要的是,它们永远不会交换到磁盘,并且可以在您使用完后立即处理掉。

它们使用起来很棘手,因为您一次只能构建一个字符(鼓励您通过在用户键入密码时捕获按键来构建它们),并且需要三行代码来恢复然后擦除它们的纯文本,但是如果使用得当,它们可以避免虚拟内存漏洞,从而使程序更加安全。

在示例结束时, SecureString 被转换为常规托管字符串,这使其再次容易受到攻击(确保在完成后使用 try-catch-finally 模式将字符串归零)。SecureString 的用途是通过限制垃圾收集器对值进行复制的数量来减少攻击的表面积,并降低被写入交换文件的可能性。

// Make a SecureString
SecureString sPassphrase = new SecureString();
Console.WriteLine("Please enter your passphrase");
ConsoleKeyInfo input = Console.ReadKey(true);
while (input.Key != ConsoleKey.Enter)
{
   sPassphrase.AppendChar(input.KeyChar);
   Console.Write('*');
   input = Console.ReadKey(true);
}
sPassphrase.MakeReadOnly();

// Recover plaintext from a SecureString
// Marshal is in the System.Runtime.InteropServices namespace
try {
   IntPtr ptrPassphrase = Marshal.SecureStringToBSTR(sPassphrase);
   string uPassphrase = Marshal.PtrToStringUni(ptrPassphrase);
   // ... use the string ...
}
catch {
   // error handling
} 
finally {
   Marshal.ZeroFreeBSTR(ptrPassphrase);
}

回答by Matthew M.

It costs somewhere in the neighborhood of $30,000 to become properly compliant and to be able to do that kind of stuff. You are better off using a 3rd party payment service. Personally, I recommend Element Express, and they have a "Hosted" solution that bypasses the PCI-DSS PAPDB compliance. I've had to convert to this for my own applications, even a Point of Sale machine!!! It's a big pain, but we're a small company.

达到适当的合规性并能够做那种事情的成本大约在 30,000 美元左右。您最好使用第 3 方支付服务。就个人而言,我推荐 Element Express,他们有一个“托管”解决方案,可以绕过 PCI-DSS PAPDB 合规性。我不得不为我自己的应用程序转换到这个,甚至是销售点机器!!!这是一个很大的痛苦,但我们是一家小公司。

http://www.elementps.com/software-providers/our-security-edge/hosted-payments/PA-DSS-Certification-vs-Elements-Hosted-Payments/

http://www.elementps.com/software-providers/our-security-edge/hosted-payments/PA-DSS-Certification-vs-Elements-Hosted-Payments/

The above link has some good information about the costs associated with becoming compliant. We have had customers ask us to store credit card numbers, and we won't do it because we could be fined as well. Not good. Don't open yourself up to liability.

上面的链接提供了一些关于与合规相关的成本的好信息。我们曾有客户要求我们存储信用卡号码,但我们不会这样做,因为我们也可能会被罚款。不好。不要让自己承担责任。

Edit:

编辑:

Additionally, if you DO decide to store the credit card information you definitely need to consider the forms of encryption you are going to use. Symmetric ? Asymmetric ?

此外,如果您决定存储信用卡信息,您肯定需要考虑将要使用的加密形式。对称 ? 不对称?

If you do Symmetric encryption (Passkey) then you open yourself up to some serious security vulnerabilities if the server(site) that has the key (needed to encrypt) is compromised in any way. Remember, even compiled code won't hide a text key.

如果您进行对称加密(Passkey),那么如果拥有密钥(需要加密)的服务器(站点)以任何方式受到损害,您就会面临一些严重的安全漏洞。请记住,即使已编译的代码也不会隐藏文本键。

If you use Asymmetric encryption (public/private keypairs) then you run into some additional issues, but if the primary public facing server is compromised they will only have the public key, and if they also access your database.. they won't be able to decrpyt the contents.

如果您使用非对称加密(公钥/私钥对),那么您会遇到一些额外的问题,但是如果面向公众的主要服务器受到威胁,他们将只有公钥,如果他们也访问您的数据库......他们将不会能够解密内容。

The question then is, where do you store the private key ? Do you have someone paste it in from their local computers when running admin functions.. have a separate application that runs on the desktop to view orders, etc.

那么问题是,您将私钥存储在哪里?你有没有人在运行管理功能时从他们的本地计算机粘贴它..有一个单独的应用程序在桌面上运行以查看订单等。

There are a lot of things to take into consideration.

有很多事情需要考虑。

Final note: Use a payment gateway (Element Express, Authorize.NET, Paypal, etc.) and don't store any credit card info locally. :P

最后一点:使用支付网关(Element Express、Authorize.NET、Paypal 等)并且不要在本地存储任何信用卡信息。:P

Here is a link about using X509 Asymmetric Encryption in C#: http://www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html

这是一个关于在 C# 中使用 X509 非对称加密的链接:http: //www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html

回答by Jamie Wright

I have a blog post that deals with this exact situation of storing sensitive data in the database. The blog post uses a String Encryptor class that I built using a Triple DES algorithm but you can plug in your own if you would like.

我有一篇博客文章讨论了在数据库中存储敏感数据的确切情况。该博客文章使用了我使用 Triple DES 算法构建的 String Encryptor 类,但您可以根据需要插入自己的类。

The blog post contains the video and source code that was used. You can check it out at http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-in-nhibernateactive-record-video.html. I think it will definitely solve your issue.

博客文章包含使用的视频和源代码。您可以在http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-in-nhibernateactive-record-video.html 上查看。我认为它肯定会解决您的问题。

回答by phpslacker

Lets look at the requirement a little differently. Currently it looks like this:

让我们以不同的方式看待需求。目前它看起来像这样:

As a product owner for website X i want the system to temporarily store a customers cc details so that i can recover a sale that was declined by the CC company

作为网站 X 的产品所有者,我希望系统暂时存储客户的 cc 详细信息,以便我可以恢复被 CC 公司拒绝的销售

Ppl tend to think like that and request features in that manner. Now i think your requirement is more conveniently described as follows:

Ppl 倾向于这样思考并以这种方式请求功能。现在我认为您的要求更方便地描述如下:

As a user i want website X to be able to retry payment for my purchase so i dont have the hassle of having to go thru the checkout process again coz that is a real pain in the...

作为用户,我希望网站 X 能够为我的购买重试付款,这样我就不必再经历结账流程的麻烦,因为这真的很痛苦……

So there's no explicit requirement for storing anything (on your side) is there? Its only implied

所以没有明确要求存储任何东西(在你身边)是吗?它唯一的暗示

Payment providers can provide programmatic APIs to your merchant account and the ability to attempt a re-auth on a declined attempt. i think @bashmohandes eluded to this earlier

支付提供商可以为您的商家帐户提供编程 API,并能够在被拒绝的尝试时尝试重新验证。我认为@bashmohandes 早些时候回避了这一点

Not all payment providers can do this however i think its dependent on their relationships with the banks involved. Thats the stuff you want to avoid ie. having a close relationship with banks.

并非所有支付提供商都能做到这一点,但我认为这取决于他们与相关银行的关系。这就是你想要避免的东西,即。与银行关系密切。

Scenario 1: Assuming all i said is true

场景一:假设我说的都是真的

You don't have to store anything but a reference to the authorization attempt. Some payment providers even give you a sweet backoffice tool so you dont have to make your own to do re-auths. I think paygate does this

除了对授权尝试的引用之外,您不必存储任何内容。一些支付提供商甚至为您提供了一个不错的后台工具,因此您不必自己制作重新验证。我认为 paygate 这样做

Your best bet i believe is to interview a number of payment providers. they should know this stuff like the back of their hands. This is potentially a zero-code solution

我相信你最好的选择是采访一些支付提供商。他们应该知道这些东西就像他们的手背一样。这可能是一个零代码解决方案

Scenario 2: Assuming i'm like totally wrong but legally this storing CC stuff is ok

场景 2:假设我完全错了,但从法律上讲,这种存储 CC 内容是可以的

So you have to store that data somewhere temporarily. I advise:

因此,您必须暂时将该数据存储在某个地方。我建议:

  • use a 2-way encryption method (naturally) that is non-vendor specific so you can use any language/platform to encrypt/decrypt
  • decouple the encrypt/decrypt service from your app and treat it like a black box
  • use public/private keys for authentication to this service
  • put this machine on a private network with its own elevated firewall rules (doesn't have to be a hardware firewall but hardware is better)
  • have your app servers communicate with this machine via ssl (you could get away with a self-signed cert since its on your private LAN)
  • 使用非供应商特定的 2 向加密方法(自然),因此您可以使用任何语言/平台来加密/解密
  • 将加密/解密服务与您的应用程序分离,并将其视为黑匣子
  • 使用公钥/私钥对此服务进行身份验证
  • 将这台机器放在具有自己提升的防火墙规则的专用网络上(不必是硬件防火墙,但硬件更好)
  • 让您的应用服务器通过 ssl 与这台机器通信(您可以使用自签名证书,因为它在您的专用 LAN 上)

All i've suggested in scenario 2 is hurdles but eventually persistence wins the race to get to your data. The only way to absolutely secure data is to unplug your server from the ether but that option is a little radical :-)

我在场景 2 中所建议的只是障碍,但最终持久性赢得了获取数据的竞赛。绝对保护数据的唯一方法是将您的服务器从以太网上拔下,但该选项有点激进:-)

Scenario 1 would be nice. Wouldn't it?

场景1会很好。不是吗?

回答by Ron Robinson

Consider your t logs!

考虑您的 t 日志!

If you explain to your customer the full impact (and remedial requirements if they are found out of compliance) then trust me, your 'business requirements' will change very quickly.

如果您向客户解释了全部影响(以及发现不合规的补救要求),那么请相信我,您的“业务要求”将很快发生变化。

If you must store the credit card number (and I advance the thought here that there is no reasonable scenario where you should) and you intend to use a native encryption built-in to your database, then consider this: what about your transaction logs?

如果您必须存储信用卡号(并且我在这里提出了您应该存储的合理方案)并且您打算使用内置于您的数据库的本机加密,那么请考虑:您的交易日志呢?

If your transaction logs could reflect a credit card number in the clear, then you are out of compliance and should budget for a $10,000 to $50,000 forensic audit at your site if you get caught. Budget for your own attorney in case your customer sues you because you should have known all this stuff.

如果您的交易日志可以清楚地反映信用卡号,那么您就是不合规,如果您被抓住,您应该在您的站点预算 10,000 至 50,000 美元的法医审计。为您自己的律师制定预算,以防您的客户起诉您,因为您应该知道所有这些事情。

So if you are going to store a credit card number, run the cipher in code so the transaction logs (insert or update) reflect a ciphered string, not the card number in the clear.

因此,如果您要存储信用卡号,请在代码中运行密码,以便交易日志(插入或更新)反映加密字符串,而不是明文的卡号。

And don't even have a field or column in your database for CVV - encrypted or not - that forensic audit will reveal this (so will the logs) and then your customer is in BIG, BIG trouble. They willpay a fine and couldlose their ability to accept credit cards. Your attorney will be very happy.

甚至在您的数据库中没有用于 CVV 的字段或列 - 加密与否 - 取证审计将揭示这一点(日志也是如此),然后您的客户就会遇到很大的麻烦。他们支付罚款,并可能失去接受信用卡的能力。你的律师会很高兴的。