有人正在存储信用卡数据 - 他们是如何做到的?
安全合法地存储信用卡信息非常困难,不应尝试。我无意存储信用卡数据,但我很想弄清楚以下问题:
我的信用卡信息存储在世界某个地方的服务器上。这些数据(希望)不会存储在商家的服务器上,但在某些时候需要存储它以验证商家提交的数据所识别的帐户并对其进行收费。
我的问题是:如果您的任务是存储信用卡数据,您会使用什么加密策略来保护磁盘上的数据?据我所知,提交的信用卡信息或多或少都会被实时检查。我怀疑用于保护数据的任何加密密钥都是手动输入的,因此解密是动态完成的,这意味着密钥本身存储在磁盘上。您将如何在这样的自动化系统中保护您的数据和密钥?
Storing credit card information securely and legally is very difficult and should not be attempted. I have no intention of storing credit card data but I'm dying to figure out the following:
My credit card info is being stored on a server some where in the world. This data is (hopefully) not being stored on a merchant's server, but at some point it needs to be stored to verify and charge the account identified by merchant submitted data.
My question is this: if you were tasked with storing credit card data what encryption strategy would you use to secure the data on-disk? From what I can tell submitted credit card info is being checked more or less in real time. I doubt that any encryption key used to secure the data is being entered manually, so decryption is being done on the fly, which implies that the keys themselves are being stored on-disk. How would you secure your data and your keys in an automated system like this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
为了回答您的具体问题,可以将加密的信用卡加密密钥存储在磁盘上。密钥加密密钥可以从服务器启动时必须输入的密码派生。可以使用 Shamir 的秘密分割方案,以便需要 N 个份额中的 k 个来构造将用作密钥加密密钥的秘密。然后将解密的加密密钥/秘密存储在存储器中。如果服务器必须重新启动,则需要 k 个共享。这当然是一个很大的开销,我认识的大多数商家都没有实现这一点。然而,为了某种中间安全性,他们通常将密钥与加密数据分开存储,因此访问一个密钥并不自动意味着完全访问另一个密钥(尽管仍然很糟糕)。
我删除了原始帖子的内容,因为它没有直接回答问题。可以说,密钥管理和正确的加密是重要的一部分,但仍然只是故事的一小部分。
PCI 审核员不可能确保一切都正确完成。
To answer your specific question, it is possible to store the credit card encryption key encrypted on disk. The key encrypting key can derived from a passphrase that must be entered when the server is started. Shamir's secret splitting scheme can be used so that k out of N shares are required to construct the secret that will be used as key encrypting key. The decrypted encryption key/secret is then stored in memory. If the server has to be restarted, then you need k shares. This is of course a big overhead and most merchants I know do not implement this. They do however usually store the key separately from the encrypted data for some intermediate security, so access to one does not automatically mean access to the other in entirety (still very bad though).
I deleted contents of my original post since that did not directly answer the question. Suffice it to say that key management and correct encryption are an important piece but still a small part of the story.
PCI auditors cannot possibly ensure that everything is done correctly.
如果您想消除任何令人头痛的信用卡盗窃问题,请使用未存储在数据库中的盐值(除了存储在数据库中的盐值之外)对它们进行哈希处理。使用任何现代哈希算法对它们进行哈希处理几乎可以解决大多数信用卡盗窃问题,但这确实意味着消费者必须在每次购买时重新输入信用卡。在参与了一个处理信用卡号存储的项目后,我发现对它们进行哈希处理可以将安全审查成本降低一个数量级(假设该项目是在 PII 问题之前)。
如果您打算使用对称加密,那么您将进入一个新的复杂领域,这一切都取决于对解密密钥的管理和控制。我想说的是,即使您对信用卡号进行哈希处理,您仍然需要处理可逆加密,因为所有 PII(个人身份信息)都必须加密。 SQL Server 2008 有一个新的可扩展密钥管理插件架构,允许使用第三方供应商程序来管理对解密密钥(包括拆分密钥)的控制。
欲了解更多信息:
根据支付卡行业数据安全标准 (PCI DSS) 1.2 版部署 SQL Server 2008。< /a>
If you want to eliminate any credit card stealing headaches, hash them using salt values not stored in the database (in addition to salt values stored in the database). Hashing them with any modern hashing algorithm will pretty much put to rest most issues with credit card theft but it does mean consumers must re-enter their credit card on each purchase. Having worked on a project that dealt with storage of credit card numbers, I found that hashing them cut security review costs by an order of magnitude (granted that project was before PII concerns).
If you are going to use symmetrical encryption, then you enter a new realm of complication that all comes down to management and control over the decryption keys. I will say that even if you hash the credit card numbers you will still need to deal with reversible encryption since all PII(Personally Identifiable Information) must be encrypted. SQL Server 2008 has a new Extensible Key Mangement plugin architecture which lets use third-party vendor programs to manage control over the decryption keys including split keys.
For more info:
Deploying SQL Server 2008 Based on Payment Card Industry Data Security Standards (PCI DSS) Version 1.2.
任何用于解密加密信息的自动化系统都将是完全不安全的。通过自动化该过程,您就可以破解加密。任何加密数据只能由用户输入的密钥解密。
any automated system for decrypting encrypted information is going to be completly insecure. By automating the process you are defeating the encryption. Any encrypted data should only be decrypted by a user entered secret key.
如果我存储这个号码,我将成为一个拥有庞大数据库的巨型服务提供商。该数据库分布在高度冗余的存储阵列中,该阵列由多个机柜组成,位于不同的房间或理想情况下位于不同的地理位置,并通过 SAN 连接。我面临的最大的内部威胁是分布式物理工厂、不断出现的磨损驱动器以及技术人员、管理员和工程师的每日轮班。这是一个巨大的威胁。
因此,我会在通过网络连接到大容量存储的物理隔离计算机上加密数据。该软件将尽可能简单:加密和数字验证。公共接口和业务逻辑去了其他地方。访问将被记录到单独的 SAN 中。
使用 AES 等加密。原始 AES 密钥仅存储在 RAM 中。密钥封装在每个管理员的 PGP 文件中,每个管理员都有自己的密码来启用服务器。可以为不太受信任的人员提供部分密码以用于灾难恢复,或者可以将密码存储在某处的保管库中。对于加密,为每个卡号选择一个唯一的初始化向量 (IV),使用该 IV 对号码进行 AES 加密,并将 IV 和加密号码存储到 SAN。仅使用特权客户端接口进行解密;用于购买的普通客户端连接永远无法获得解密。
If I was storing the number, I would be a giant service provider with a massive database. That database is spread across a highly-redundant storage array consisting of multiple cabinets, in separate rooms or ideally in separate geographical locations, connected by a SAN. My biggest insider threat is the distributed physical plant, the constant stream of worn-out drives, and several daily shifts of technicians, administrators, and engineers. It's a huge threat.
Therefore I would encrypt the data on a physically-isolated computer that connects to the mass storage over a network. The software would be as simple as possible: encryption and number verification. The public interfaces and business logic goes elsewhere. Accesses would be logged to a separate SAN.
Encrypt with something like AES. The raw AES key is only ever stored in RAM. The key is wrapped in a PGP file for each administrator, who has their own passphrase to enable the server. Less-trusted personnel can be given partial passphrases to use in disaster recovery, or passphrases can be stored in a vault somewhere. For encryption, pick a unique initialization vector (IV) for each card number, AES-encrypt the number using that IV, and store the IV and encrypted number to the SAN. Decryption only occurs using a privileged client interface; normal client connections used for purchases can never get a decryption.
对于处理和存储您的信用卡信息的供应商来说,他们通常必须获得 PCI 认证。应在此处概述这些要求。有些要求非常简单,而另一些要求则含糊不清并且可以解释。完成这个过程并不有趣,并且拥有认证的公司并不意味着您的数据是安全的。
但我想这总比没有好。
For vendors to process and store your credit card info, they generally have to get PCI certified. The requirements should be outlined here. Some of the requirements are very straightforward, and others are vague and open to interpretation. Going through the process is not fun, and a company having the certification doesn't mean your data is safe.
But it's better than nothing I suppose.
为了安全查找,存储信用卡号码的加盐哈希值而不是号码本身非常容易。对于 99% 的情况,信用卡足以用于存储——快速且非常安全。
如果您确实需要在某些情况下对信用卡进行可逆加密(例如,持续计费),我会使用存储在安全位置的对称密钥,而不是存储在数据库。我已经有一段时间没有查看 PCI 规范了,但我相当确定它符合 PCI 标准。
如果您需要快速查找和可逆加密,请使用两个选项:哈希和加密。
编辑:
看来我的回答还有点争议。我想指出以下来自 Integrity.com (PDF) 的非常有趣的文章:
散列信用卡号:不安全的应用程序实践
它详细介绍了存储信用卡数据散列所涉及的许多问题,但其结论证实了我的建议。
是的,卡的原始哈希值并不安全;这就是为什么我们给哈希加盐!但静态盐也不安全,它们允许为已知的静态盐创建彩虹表。所以最好让我们的盐以某种不可预测的方式变化。对于密码来说,对每个要检查的密码使用单独的随机散列就足够了;它甚至可以与散列密码驻留在同一表/行中。对于信用卡的情况,这应该是相同的——为被散列的信用卡的每个实例提供一个随机盐。如果每笔交易都存储信用卡号,则每笔交易都有一个单独的盐。
这种方法有优点也有缺点,但它足够安全。优点是缺乏关键管理;盐和哈希值就在那里,不需要更改,同时仍然允许对哈希值进行审计检查;例如,该信用卡哈希值是否与该已知信用卡号匹配?
缺点在于搜索;不可能在许多交易中有效地搜索特定的信用卡号。
当然,无论如何,您都会遇到外部加密的问题;除非数据库本身是加密的(只有某些数据库支持),否则您将无法很好地进行搜索。即使如此,在数据库甚至表级别进行加密也会显着降低搜索效率。
It's quite easy to store a salted hash of a credit card number rather than the number itself for secure lookups. For 99% of the scenarios out there, this would be sufficient credit card for storage -- fast and very secure.
If you really need reversible encryption of a credit card for some scenario (continued billing, for example), I would go with a symmetric key stored in a secure location other than the database. It's been a while since I looked at PCI specs, but I'm fairly certain that's PCI compliant.
If you need fast lookups along with reversible encryption, use both options: a hash and an encryption.
Edit:
There seems to be some controversy over my answer. I would like to point out the following very interesting essay from Integrity.com (PDF):
Hashing Credit Card Numbers: Unsafe Application Practices
It details many of the issues involved in storing a hash of credit card data, but its conclusion confirms my suggestion.
Yes, a raw hash of the card is not secure; that's why we salt our hashes! But a static salt is also not secure, they allow the creation of rainbow tables for known static salts. So it's best to make our salts vary in some way that is unpredictable. In the case of passwords, it's sufficient to use a separate, random hash for each password being checked; it can even reside in the same table/row as the hashed password. For the case of credit cards, this should be the same -- a random salt for each instance of the credit card being hashed. If the credit card number is stored per transaction, a separate salt for each transaction.
There are pros and cons to this approach, but it's sufficiently secure. The pros are the lack of key management; the salt and hash are right there, and don't need to change while still allowing for audit checks of the hash; e.g. does that credit card hash match this known credit card number?
The cons are in search; it's not possible to effectively search for a particular credit card number across many transactions.
Of course, you'll have this issue with external encryption anyway; unless the database is itself encrypted (something only some databases support), you won't be able to search very well. Even then, encrypting at the database or even the table level reduces search effectiveness significantly.
过去几次我使用信用卡付款时,您从未真正将实际的 CC 信息存储在您自己的服务器上。您让支付网关处理该问题。您最终得到的是一个 transactionID,您可以使用它来验证信用卡是否仍然有效并且具有所请求的可用现金金额。然后,一旦您真正打包了他们购买的东西,您就可以向支付网关发出捕获命令。
这种方法极大地简化了在网站上集成 CC 支付的过程,因为您只需要知道特定客户的交易 ID。这当然不允许您像亚马逊那样保留您的 CC 信息以进行一键购物。如果 transactionID 被泄露,它的唯一用途就是提前收取付款,或者完全取消交易(在这种情况下,当您在发货前验证授权仍然有效时,您就会发现这一点)。该交易不能用于收取比客户已经批准的金额更大的金额,也不允许某人收取到与“商店”配置不同的帐户。
也许不是您正在寻找的确切答案,但也许它可以解决您的整体问题,而无需在安全供应商身上花费大量资金。
The last few times I worked with creditcard payments, you never really stored the actual CC info on your own servers. You let the Payment gateway handle that. What you ended up with was a transactionID that you could use to verify that the creditcard was still both valid and had the requested amount of cash available. Then once you actually packed the stuff they bought, you'd issue a capture-command to the Payment Gateway.
This approach greatly simplified the process of integrating CC payments on a site, since all you ever needed to know was the transactionID for a particular customer. This ofcourse didn't allow you do to the amazon-"trick" of keeping your CC info for 1-click shopping. If the transactionID got compromised, all it could be used for was collecting payment early, or cancelling the transaction altogether (in which case you'd find out about it when you verified that the authorization was still valid before shipping). The transaction couldn't be used to collect a bigger sum than what the customer had approved already, nor would it allow someone to collect to a different account than what the "shop" was configured for.
Maybe not the exact answer you were looking for, but perhaps it could solve your overall issue without having to spend a fortune on security vendors.
您关于商家必须以某种方式存储卡的假设是不正确的。最有可能的是,商家正在存储您第一次使用该卡时从支付处理网关收到的令牌。令牌唯一标识商户和卡的组合。随后,您可以从该商家处购物,而无需再次提供您的卡号。如果商家的数据库遭到破坏,那么这些代币对攻击者来说就没有什么价值。它们仅对该商家有效,并且在检测到违规行为时可以立即取消。
Your assumption that the merchant must store the card somehow is incorrect. Most likely, the merchant is storing a token that it received from the payment processing gateway the first time you used the card. The token uniquely identifies the combination of merchant and card. Subsequently, you can make purchases from that merchant without supplying your card number again. If the merchant's database is compromised, the tokens are of little value to the attacker. They're only valid for that merchant, and they can all be canceled at once when the breach is detected.
在某些情况下,加密密钥不存储在磁盘上,而是存储在某些硬件设备上。要么使用特殊的加密服务器来进行加密/解密,要么使用存储在硬件加密狗上的密钥来完成解密。这样,黑客就无法在不窃取包含解密密钥的物理设备的情况下窃取解密密钥(因为密钥永远不会离开设备)。
我见过的另一种方法是将加密数据存储在与外界没有直接连接的数据库/数据中心中(你无法破解你无法访问的内容)。接口服务器作为代理位于网络的“安全”部分和网络的“面向互联网”/“不安全”部分之间。强制安全流量通过此安全阻塞点可以使入侵者更难访问受保护的数据。
当然,这些都不意味着您的数据是完全安全的。
In some situations, encryption keys are stored not on disk but on some hardware device. Either a special encryption server is used to do the encrypt/decrypt or the decrypt is done using a key stored on, say, a hardware dongle. This way, a hacker cannot steal the decrypt keys without stealing the physical device containing them (since the key never leaves the device).
Another method I have seen is to store encrypted data in a database/datacenter that has no direct connection to the outside world (you can't hack what you can't access). An interface server sits between the "secure" part of the network and the "Internet-facing"/"insecure" part of the network as a proxy. Forcing secure traffic to funnel through this security choke point can make it more difficult for an intruder to access the secured data.
Neither of these mean your data is perfectly secure, of course.
作为商家,您可以选择将 CC 数据存储在您自己的数据库中或将其外包给第三方提供商。
第三方提供商,如 IPPayments 或主要银行,如 澳大利亚西太平洋银行符合 1 级 PCI 标准。对于 Web 应用程序,您可以选择使用您公司品牌的付款接受网页(在客户工作流程中的某个位置显示)。对于Windows应用程序(例如您公司的CRM应用程序)和定期付款,他们通常有一个可使用其API使用的网关,该API提供令牌化服务,也就是说,他们接受CC号码,注册它并返回一个看起来像CC号码的唯一令牌。该令牌可以安全地存储在您的数据库中,并用于与银行的任何进一步交易、批量支付、对账等。当然,他们的大问题是每笔交易的运营成本。对于每月从一百万客户处收取信用卡付款的公用事业公司来说,交易成本可能会很高。
如果您选择将 CC 号存储在您自己的 DB 中,三重 DES 加密就足够了。更好的选择是 Oracle 高级安全性或 SQLServer 提供的 DB 透明加密,即使 DBA 也无法解密 CC 号。然后还有密钥管理、备份、物理安全、网络安全、SSL传输、更改所有服务器设备和防火墙的默认设置、防病毒、审计、安全摄像头等等繁重的责任......
As an merchant you can choose to store the CC data in your own database or outsource it to third party providers.
Third party providers like IPPayments or major banks like Westpac in Australia are level 1 PCI compliant. For web applications you can choose to use a payment acceptance web page (presented somewhere in your customer's workflow) from them branded for your company. For windows apps (e.g. you company's CRM app) and recurrent payments they generally have a gateway usable using their API that provide a tokenisation service, that is they accept a CC number, registers it and return an unique token that just looks like a CC number. The token can be safely be stored in your DB and used for any further transactions, batch payments, reconciliation etc with the bank. Of course they big issue is operational cost per transaction. For a utility that takes monthly credit card payment from a million customer the transaction cost can be substantial.
If you choose to store the CC number in your own DB triple DES encryption is sufficient. A better option is to you transparent encryption in DB as offered by Oracle advanced security or SQLServer where even the DBA cannot decrypt the CC number. Then there are onerous responsibility for key management, backup, physical security, network security, SSL transmission, changing default settings of all server equipments and firewall, anti virus, auditing, security cameras and on and on ...
首先,如果您处理信用卡号码,则需要符合 PCI-DSS 合规性,并且一旦存储PCI-DSS 规范的所有 12 个部分都适用于您。这对大多数组织来说都是一项重大成本,如果您没有时间、资源和财务手段,则不应走上存储信用卡号的道路。
我们在基于 Windows 的存储信用卡的电子商务系统上获得了 PCI-DSS 合规性。它使用 256 位 AES 加密。密钥本身使用 Windows DPAPI 进行加密,这意味着它只能通过在与加密它的用户帐户相同的用户帐户下运行的进程。加密的密钥存储在注册表中。
密钥每 12 个月轮换一次,备份密钥副本分为 3 个部分 A、B、C,并分布在 3 个 USB 驱动器上,每个驱动器由不同的人持有。驱动器 1 有 A+B,驱动器 2 有 B+C,驱动器 3 有 A+C。因此,需要任意 2 个驱动器才能构建完整密钥 (A+B+C)。该方案可以容忍任何 1 个驱动器的丢失。关键部分本身使用只有驱动器所有者知道的密码进行加密。
First of all if you deal with credit card numbers, you will need to become PCI-DSS compliant, and once you store numbers all 12 sections of the PCI-DSS spec will apply to you. Thats a major cost to most organisations, and if you don't have the time, resources and financial means, you should not go down the path of storing credit card numbers.
We have gained PCI-DSS compliance on a Windows based e-commerce system that stores credit cards. It uses a 256 bit AES encryption. The key itself is encrypted using Windows DPAPI meaning it can only be decrypted by a process running under the same user account as the one that encrypted it. The encrypted key is stored in the registry.
The key is rotated every 12 months, and a backup key copy is stored broken into 3 parts A,B,C and spread over 3 USB drives, each held by a different person. Drive 1 has A+B, Drive 2 has B+C, Drive 3 has A+C. So any 2 drives are required to construct a full key (A+B+C). This scheme is tolerant to the loss of any 1 of the drives. Key parts themselves are encrypted with a password known only to the drive owner.