49

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

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

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

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

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

4

10 回答 10

49

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

于 2008-10-15T21:03:02.190 回答
14

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

于 2008-10-15T21:18:15.857 回答
14

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

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

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

上次我查看该标准时,并没有具体针对加密算法,而是明确表示它应该是当前不可破解的加密。

现在,您不能做的一件事是在授权后存储 CCV。我的理解是,您可以在授权之前存储它,但我永远无法让任何人把它写下来。基本上,您对卡进行了授权,最好将其擦除。

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

最终,我相信他们真正拥有的唯一手段就是阻止您接受信用卡。大多数与我合作过的商人都被吓死了。

于 2008-10-15T21:47:50.353 回答
8

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

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

于 2008-10-15T21:17:28.107 回答
8

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

取自这个答案

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);
}
于 2008-10-15T22:43:30.647 回答
6

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

于 2008-10-15T21:14:40.467 回答
6

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

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

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

编辑:

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

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

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

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

有很多事情需要考虑。

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

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

于 2008-10-16T00:58:25.273 回答
4

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

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

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

作为用户,我希望网站 X 能够为我的购买重试付款,这样我就不必再经历一次结帐过程了,因为这在...

所以没有明确要求存储任何东西(在你这边)吗?它只暗示

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

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

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

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

我相信你最好的选择是采访一些支付提供商。他们应该对这些东西了如指掌。这可能是一个零代码解决方案

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

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

  • 使用非供应商特定的 2 路加密方法(自然),因此您可以使用任何语言/平台来加密/解密
  • 将加密/解密服务与您的应用程序分离,并将其视为黑匣子
  • 使用公钥/私钥对该服务进行身份验证
  • 将此机器放在具有自己提升的防火墙规则的专用网络上(不必是硬件防火墙,但硬件更好)
  • 让您的应用服务器通过 ssl 与这台机器通信(您可以使用自签名证书,因为它在您的私有 LAN 上)

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

场景1会很好。不会吗?

于 2010-05-11T06:48:05.233 回答
4

考虑你的日志!

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

如果您必须存储信用卡号(并且我在此提出了一个想法,即没有合理的情况应该存储)并且您打算使用内置到数据库中的本机加密,那么请考虑一下:您的交易日志呢?

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

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

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

于 2012-09-25T21:19:24.910 回答
0

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

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

于 2008-11-07T14:18:39.180 回答