存储信用卡详细信息

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

理由:如果客户打电话订购产品,并且他们的信用卡在现场被拒绝,您可能会失去销售。 如果你把他们的细节,感谢他们的交易,然后发现卡被拒绝,你可以给他们打电话,他们更可能find另一种方式来支付产品。 如果信用卡被接受,则清除订单中的详细信息。

我无法改变这一点。 现有的系统以明文forms存储信用卡详细信息,并且在我正在build造的新系统中replace这个我显然不会复制这个!

那么我的问题就是如何在短时间内安全地存储信用卡。 我显然想要一些encryption,但最好的办法是什么?

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

基本上避免采取责任保存CC的细节在你身边,但是我可以假设你正在使用第三方服务来做你的交易,如贝宝/ Verisign或其他,其中大多数都有API的,使您可以保存CC凭证,然后他们给你一个密钥,稍后你可以使用它来完成或启动事务处理,所以他们要处理困难的部分,而你所要做的就是把这个string密钥存储在数据库中。

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

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

首先,从你描述的情景中,我将试图授权卡的全额,然后如果失败,我会存储客户的信息(但不是持卡人的数据),以便有人可以联系用户。 我在哪里工作,我们的一些客户只收取1.00美元,然后立即撤消交易,只是为了确保卡是有效的。 他们然后会手动处理所有的订单。

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

这个标准,我上次看到的,不是encryptionalgorithm的具体规定,而是明确的说明它应该是当前不可破解的encryption。

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

在这一点上这不是非法的,但如果你被钉上了,他们会把锤子打倒在你身上。 他们有权力对你判处巨额罚款,但他们通常所做的就是把你们整治。 如果你不遵守,我不知道会发生什么,因为我听说每个人都听到这个情况。 但是,他们真的用显微镜上去了你的战利品。

最终,我相信他们唯一的坚持就是阻止你接受信用卡。 大部分我曾与之合作过的商人都害怕死亡。

如果你只是想在短时间内存储string,你可以看看System.Security.SecureString 。

从这个答案采取:

SecureString的值被encryption存储(相反),但最重要的是,它们永远不会交换到磁盘,并可以在您完成后立即处理。

他们使用起来很棘手,因为你一次只能build立一个angular色(鼓励你通过在用户input密码时捕获击键来build立它们),并且需要三行代码来恢复,然后擦除纯文本,但是如果使用得当,他们可以通过避免虚拟内存漏洞使程序更安全。

在这个例子的最后,SecureString被转换成了一个常规的托pipestring,这又使得它变得易受攻击(确保在完成之后使用try-catch-finally模式对string进行清零)。 SecureString的使用是通过限制垃圾收集器对该值的拷贝数量来减less攻击的表面积,并减less被写入交换文件的可能性。

// 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); } 

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

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

它花费在3万美元附近的某个地方,以便正确地遵守规定并能够做到这一点。 您最好使用第三方支付服务。 我个人推荐Element Express,他们有一个“托pipe”的解决scheme,绕过了PCI-DSS PAPDB合规性。 我不得不转换到这个为我自己的应用程序,甚至一个销售点的机器! 这是一个很大的痛苦,但我们是一个小公司。

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

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

编辑:

另外,如果您决定存储信用卡信息,您肯定需要考虑您要使用的encryptionforms。 对称? 不对称?

如果您使用对称encryption(密钥),那么如果具有密钥(需要encryption的)的服务器(站点)以任何方式受到攻击,则会导致严重的安全漏洞。 请记住,即使编译的代码也不会隐藏文本键。

如果你使用非对称encryption(公钥/私钥对),那么你会遇到一些额外的问题,但是如果面向主服务器的公共服务器被攻破,他们将只有公钥 ,如果他们也访问你的数据库..他们不会能够清除内容。

那么问题是,你在哪里存储私钥? 在运行pipe理function时,是否有人将其从本地计算机粘贴进来?在桌面上运行单独的应用程序以查看命令等。

有很多事情要考虑。

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

以下是在C#中使用X509非对称encryption的链接: http : //www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html

同意你应该避免存储数据。 但也许你第三方? 如果是,请熟悉PCI标准 。 在网站上查看一下,你会发现你需要实施的安全措施。

让我们看看需求有点不同。 目前看起来像这样:

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

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

作为一个用户,我希望网站X能够重试我的购买付款,所以我没有必须通过结帐过程的麻烦再次因为这是一个真正的痛苦… …

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

支付提供商可以为您的商家帐户提供程序化的API,并能够尝试拒绝尝试重新授权。 我认为@bashmohandes早些时候避开了这一点

不是所有的支付提供商都可以这样做,但我认为它依赖于他们与银行的关系。 那就是你想避免的东西,即。 与银行有密切的关系。

情况1:假设我所说的是真的

除了对授权尝试的引用外,您不必存储任何内容。 一些支付提供商甚至给你一个甜蜜的backoffice工具,所以你不必让自己做重新authentication。 我认为paygate是这样做的

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

情景2:假设我是完全错误的,但在法律上这个存储CC的东西是好的

所以你必须临时存储这些数据。 我build议:

  • 使用非供应商特定的双向encryption方法(自然),因此您可以使用任何语言/平台进行encryption/解密
  • 从你的应用程序解耦encryption/解密服务,并把它当作一个黑匣子
  • 使用公钥/私钥对此服务进行身份validation
  • 把这台机器放在一个专用的networking上,并有自己的防火墙规则(不一定要是硬件防火墙,但硬件要好一些)
  • 让您的应用程序服务器通过ssl与本机通信(您可以通过自己的私有LAN获得自签名证书)

我在场景2中提出的所有问题都是障碍,但是最终的持久性会赢得比赛以获取您的数据。 绝对安全的数据唯一的方法是从以太网拔掉您的服务器,但该选项是有点激进:-)

情况1会很好。 不是吗?

考虑你的日志!

如果你向你的客户解释完全的影响(如果发现不符合要求,那么补救要求),那么相信我,你的“业务要求”将会很快改变。

如果您必须存储信用卡号码(并且我在这里提出这样的想法,即您没有合理的scheme),并且您打算使用内置于数据库的本地encryption,那么请考虑:您的交易日志呢?

如果您的交易日志可以清楚地反映信用卡号码,那么您就不符合规定,并且如果您被发现,应该在您的站点预算$ 10,000到$ 50,000的法庭审计。 如果你的顾客起诉你,因为你应该知道所有这些东西,那么为自己的律师预算。

因此,如果要存储信用卡号码,请在代码中运行密码,以便事务日志(插入或更新)反映encryption的string,而不是明文中的卡号。

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

我有一个博客文章,讨论在数据库中存储敏感数据的确切情况。 博客文章使用我使用Triple DESalgorithm构build的stringencryption器类,但是如果您愿意,可以插入自己的插件。

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