我有一个一般的加密问题。我在这里阅读了许多与加密相关的问题,但找不到任何专门解决我问题的问题。
这是假设场景:
- 我将信用卡号存储在数据库中
- 这些数字要么加密要么散列
- 面向公众的应用程序检查客户请求是否包含黑名单上的信用卡信息
- 攻击者已经破坏了数据库以及将信用卡添加到黑名单的能力。
攻击者可以在不知道加密密钥的情况下添加信用卡似乎是不现实的,但一种情况是他们向面向公众的应用程序发出请求,这似乎是欺诈,并且将让知道信用卡的应用程序自动将信用卡列入黑名单。加密密钥(这是对现实的极大简化)。
我想要一个提供以下内容的解决方案:
1)插入一张列入黑名单的信用卡,其工作时间为 O(log(n)) 或更少
2) 检查信用卡是否在黑名单上,工作时间为 O(log(n)) 或更少。例如,btree 索引可以提供 O(log(n)) 查找工作。
3) 使用加密或散列函数保护信用卡号码,这样如果数据被泄露,这些号码将无法使用。
4) 攻击者无法检查卡片是否在列表中,即使他们可以插入值并且可以看到加密/散列值。
我的问题与哈希信用卡号码用作指纹密切相关,但选择的答案说“当有新卡进来时,我们通过将其与哈希 + 加盐列进行比较来查找它。如果它与现有的列匹配,我们知道我们可以返回相同的唯一数字标识符”。此解决方案是不可接受的,因为这需要 O(n) 查找时间。换句话说,我需要检查黑名单中的每一行以查看该号码是否在列表中。
第一个提出的解决方案:典型的懒惰程序员回答
不要加密。无论如何,这些只是糟糕的欺诈数字。
失败:仅仅因为我们认为这些是坏客户的,并不意味着我们应该公开这些数字。这也不意味着我们在 100% 的时间里正确地将其列入黑名单,此外,即使客户是坏人并进行欺诈,我们仍然无权公开他们的号码。
第二个建议的解决方案:不加盐散列信用卡
这提供了快速插入和快速查找。只需再次对卡号进行哈希处理,然后检查哈希值是否在列表中。
失败:问题是攻击者可以通过简单地散列随机卡号并检查该值是否在列表中来暴力破解信用卡。即使使用慢速散列算法也是一个问题,因为有效卡号的空间很小,并且每个散列检查黑名单上可能有数百万行(请记住,这是一种假设情况。我实际上并没有存储数百万个信用卡号) .
第三个建议的解决方案:为每一行使用唯一盐的散列
这个解决方案可以很容易地用 crypt(3) 或类似的东西提供。它无缝地将盐存储在散列值中。现在,如果攻击者试图暴力破解数字,他们也将不得不暴力破解盐。这使得攻击不可行。失败:现在执行黑名单查找需要 O(n) 的工作。我们需要在每一行上调用慢散列函数,性能变得无法接受。
第四种建议的解决方案:使用存储在数据库外部的全局盐(HMAC)
进行哈希现在攻击者需要使用面向公众的 api 来执行哈希操作,而不是每秒执行数百万次离线哈希。他们不能执行离线攻击的原因是存储在数据库之外的全局盐足够长,盐不能被暴力破解。
失败:仍然存在这样一个事实,即插入检查可能存在数百万行并且信用卡状态空间很小。攻击者每天可以执行 1000 个请求,并将导致重复的请求记录在数据库中。重复项是已经在黑名单中的信用卡号
第五个建议的解决方案:通过默默无闻的
安全性失败:这不是真正的安全性。这很诱人,但假设攻击者已经破坏了数据库,那么他们很有可能是公司内部的管理员,并且可以访问我们实施的任何解决方案和算法。
第六个建议的解决方案:制作另一个较小的桌子。
将数字列入黑名单时,将带有盐的完整数字的散列存储在表 1 中,并将表 2 中最后 4 位数字的散列存储在不带盐的情况下(删除重复项)。当检查一个号码是否被列入黑名单时,检查表2。大多数情况下不会命中,检查速度很快。在极少数情况下,会出现命中,然后对表 1 进行缓慢检查。
失败:如果我存储了数千条记录,则很可能最后 4 位数字存在于此列表中。4 位数字是 10000 个唯一的组合,并且有 10000 个卡片条目,很有可能会出现命中,从而导致检查缓慢。此外,攻击者将知道表 2 中的条目将在表 1 中至少有一个匹配项。他们可以仅用 10000 个请求对表 1 进行暴力破解,现在他们已经大大减少了表 1 的搜索空间。帖子引用了 100,000,000 作为可能可能的信用卡号空间大小。表 2 会有效地将这个空间减少到 100,000,000/10,000 = 10,000。这意味着反转一个哈希的时间大约是我的应用程序检查表 1 所花费的时间(表 1 中的 10,000 行意味着 10,000 个慢速散列,而蛮力也将是 10,000 个慢速散列)
所有解决方案也适用于加密而不是散列。加密的好处是现在攻击者必须对面向公众的应用程序进行在线攻击。这仍然不能解决建议的解决方案 4 中指出的问题。此外,加密而不是散列的风险在于,如果加密密钥被泄露,攻击者会立即拥有所有纯文本值。至少通过散列,他们只能暴力破解列表中的一些卡号。
我还研究了标记化https://securosis.com/assets/library/reports/Securosis_Understanding_DBEncryption.V_.1_.pdf并且存在同样的问题,只是在重复的令牌而不是重复的哈希中。
请注意,我想要比 PCI-DSS 合规性更强的东西。解决方案 2 在技术上符合 PCI_DSS,因为不需要盐 https://www.pcisecuritystandards.org/documents/PCI_DSS_v3.pdf(PDF链接)
对不起,很长的帖子。有谁知道这是否可能?