如何安全地加密数据库中的信用卡信息

Posted

技术标签:

【中文标题】如何安全地加密数据库中的信用卡信息【英文标题】:How to securely encrypt credit card information in a database 【发布时间】:2012-06-18 06:11:00 【问题描述】:

我已经阅读了Saving credit card information in mysql database? 和Storing Credit Card Information。

我知道存储信用卡信息需要 PCI 合规性,这不是一件容易的事。

这不是这个问题的目的。我的问题如下:

加密用户信用卡的安全方法是什么?想到的最简单和最简单的方法是使用私钥并用它加密 CC。这似乎不太安全,因为密钥必须存储在服务器上,如果攻击者可以获取我的数据库,他们可能也可以获得密钥。

我希望能够使用该用户密码加密每个 CC 作为加密过程的一部分。如果有人获得数据库,他们将无法解密任何内容,因为密码存储为加盐哈希。这对于交易性购买非常有用——用户点击“购买”,输入他们的密码作为确认,我解密他们的 CC 并进行收费。他们的密码仅在请求期间在内存中,并且永远不会写入磁盘。

不幸的是,这不适用于我正在尝试构建的内容 - 一项收取经常性费用(例如,每月一次)的服务,无论用户是否在我需要收费时登录.

在这种情况下,是否有一种安全的方式来存储用户 CC?

【问题讨论】:

存储 CC 信息的服务器是否也必须能够读取 信息?例如。如果可以通过读取加密数据副本的离线机器完成每月收费,您可能需要考虑使用公钥方法... 想必系统一直是连接的,只要用户注册,数据就可以发送给它。是的,使用专用接口更容易保护,但意味着需要外部应用程序;并且可能不是标准的网络软件,否则它可能会表现出许多与原始主机相同的漏洞。第三方专业的异地解决方案可以做到这一点。 【参考方案1】:

对抄送信息进行两次加密。首先,根据用户密码(+ salt)加密信用卡数据。然后用服务器的密钥加密输出。

要访问信息,您需要用户的密码(即使用服务器的密钥解密,然后根据密码解密)。如果数据库和服务器密钥被泄露,在不首先攻击用户密码的情况下,信息仍然不会暴露。

重要的是,用户的密码用于内部加密 - 这允许您在更改服务器加密密钥时重新加密。

当用户更改密码时,您也会重新加密数据。如果用户重置了密码,那么 CC 信息应该被删除(无论如何都会丢失,因为它不能被解密)。

【讨论】:

【参考方案2】:

当用户购买时使用 php 的私有/公共 openssl 函数,您使用内存中的数据进行购买,然后使用公钥存储信息以对其进行加密。

要按月处理帐单,您可以使用可以手动输入或存储在代码中的私钥解密数据。如果您想将 ssl 密钥存储在代码中,而不必每次都记住或获取它。我将使用存储在配置变量中的盐加密密钥 + 购买一个 yubi 密钥并在其上生成一个 32 个字符的密码 + 我自己的密码。将 yubikey 存放在安全的地方(安全的哈哈)。当您需要处理信用卡时,请使用在后台运行并一次运行所有计费的脚本来完成。要更改密码,您需要解密所有卡并使用新的私钥/公钥重新加密它们,或者您可以只解密并重新加密私钥 ssl。

魔法:)

【讨论】:

【参考方案3】:

您基本上可以使用多个服务器。使用密钥加密 cc,但将该密钥保存在单独的加密服务器上,只能通过 Windows 或您正在使用的任何操作系统的主用户名和密码访问。通过这种方式,您可以保护您的密钥,在加密服务上设置服务以通过加密运行卡,然后将其提交到数据库。

【讨论】:

【参考方案4】:

由于您需要能够解密,因此始终存在加密密钥泄漏的可能性,您将失去一切。因此,您永远无法获得绝对的安全性,但可以让攻击者更难获取数据。

只有您才能真正判断您应该拥有什么级别的安全性(或隐蔽性)。这很可能是数据库大小、可见性等的函数。

对于泄漏,不幸的是,您必须假设所有内容都会泄漏,并且迟早(例如,对弱密码进行暴力攻击)当它们泄漏时您并没有获得太多收益。

鉴于上一次信用卡泄露丑闻 - 最糟糕的是 3 位数 (CVV) 号码与常规信用卡号码一起保存,信用卡公司明确禁止这种情况(这就是为什么你总是不得不再次提供它,即使如果有人记录了您的信用卡信息)

如果您不想承担持有和处理此类数据的责任,一个好方法是使用外部支付服务 - 让他们进行处理,然后向您声明付款已处理.您必须为他们的服务付费,但您还必须为实施自己的解决方案和承担风险付费。

【讨论】:

你和Shannon都提到了外部服务,比如authorize.net。如果存储 3 位数字是非法的,那么这些服务如何实现定期计费?他们是否与信用卡公司达成某种交易? 抱歉,帮不了你。我只知道 那个 信用卡公司禁止保留 3 位数字。他们可能会在其 API 中提供“定期付款”作为一种付款方式,但这只是一个疯狂的猜测。 没错。 “定期付款”是一个可以在创建交易时设置的选项。【参考方案5】:

如果您使用密码作为 CC 加密的盐,这将是保护信息的一种非常有效的方法,但是,他们将永远无法更改他们的密码......如果更改了密码,那么加密数据丢失。保护加密密钥的底线是使其尽可能难以找到......基本上你隐藏密钥的步骤越多,他们就越难找到它......这意味着它更难您可以使用它并为其编程。此时没有灵丹妙药可以保护一切。 (发明一种安全的方式来保存密钥,你就会变得富有)

至于CVV号,不能如前所述存储。对于每笔交易,抄送处理公司都会给商家一个参考号,然后在每次重复付款中使用该参考号。这意味着,如果原始交易需要 CVV 编号,那么逻辑将规定定期付款也将由在第一笔交易中输入的同一用户授权。因此,重复付款将不需要 CVV 来保持相同的安全级别。

【讨论】:

【参考方案6】:

您需要对卡信息进行可逆加密。解密信息必须来自某个地方。您已经说过数据不能来自用户,并且您不希望将其存储在服务器上,因此它必须位于可能更安全的单独设备上。如果您有能力回忆起这些信息,那么入侵您系统的攻击者也有能力回忆起这些信息。所以推测在解密过程中没有在易受攻击的主机上检索到解密信息。

也许可以考虑使用可以加密并向其发送信息的第三方服务,也许是专门从事 PCI 合规性的服务。当您第二次发送信用卡信息并收取费用时,它可能能够解密信用卡信息,或者它可能实际存储信用卡信息以供以后使用。它甚至可以为您执行定期交易。

http://www.authorize.net/solutions/merchantsolutions/merchantservices/automatedrecurringbilling/

我只是在谷歌上搜索过,我不推荐他们。但这是一个例子。

【讨论】:

@OP:欺诈预防系统需要验证码以确保在安排交易时持有卡,但为商户提供将交易识别为“重复”的能力,并且验证状态通过经常性交易。卡处理机构仍会保留卡号,但不会保留 CVV2,用于重复交易。如果您想了解更多信息,请使用 Google 信用定期交易最佳做法,但总的来说,我认为您会让其他人为您完成这项工作。

以上是关于如何安全地加密数据库中的信用卡信息的主要内容,如果未能解决你的问题,请参考以下文章

PayPal 保险库存储 - 安全地发送信用卡信息

关于存储信用卡详细信息的安全模型的思考

iOS - 从 ios 应用程序以加密形式将信用卡/借记卡存储在服务器上,然后再次从应用程序解密。我怎样才能最安全地管理它?

https加密算法解析

在 Braintree 中使用 AngularJS 加密信用卡详细信息

是否有用于信用卡加密的最佳 .NET 算法?