我运营一个网站,我们将某些帐户标记为骗子,并“标记”他们的帐户和所有使用的信用卡都不好。我们不存储实际的信用卡值,而是存储校验和/ MD5算法。
我们现在一直在碰撞。存储这些值的最佳方法是什么 - 不可逆,但能够对未来值进行比较。
我认为MD5会是最好的,但我们在这里进行辩论......
答案 0 :(得分:15)
加密安全散列可行。 (SHA512或SHA256可以)
但是,我会使用一个没有与卡一起存储的相当秘密的 salt (以防止任何类型的彩虹表攻击)。
<强> PS:强>
对信用卡的彩虹表攻击可能特别有效,因为由于字符集有限,固定大小和校验位数,纯文本空间的总大小非常小。
<强> PPS:强>
您不能为每个条目使用随机盐,因为您永远无法检查重复项。盐用于防止碰撞,而我们在这种情况下专门寻找碰撞。
答案 1 :(得分:4)
使用好的哈希算法是不够安全的。如果您的列表被盗,您存储的哈希值可用于检索工作卡信息。信用卡号码的实际模式空间足够小,以确定攻击者可以提前预先计算许多可能的哈希值,如果存在入侵或内部作业,这可能会对您的系统产生其他影响
我建议您使用盐,并根据涉及卡号和第一个盐值的每个数字的公式计算要添加到盐中的第二个值。这可以确保如果您失去对任一部分的控制,您仍然具有合理的唯一性,这使得列表的所有权无效。但是,公式不应该对卡的前6位(BIN号)进行大量加权,并且公式的跟踪不应存储在与盐或最终哈希相同的位置。
考虑一个16位信用卡号码的解剖结构:
6位BIN(银行识别码)
9位帐号
1位数的Luhn Checksum
BIN列表在加工行业中是众所周知的,并且对于那些可以访问非法卡号列表的人来说并不太难以组装。每个发行人的指定空间会进一步减少有效BIN的数量。
签证 - 从4开始 美国运通 - 从34/37开始 万事达卡 - 从5开始 发现/ CUP - 从6开始 晚餐俱乐部 - 从35开始 等
请注意,每个颁发者类别中的一些已分配的BIN信息也是稀疏的。如果攻击者知道您的大多数客户所在的位置,那么这将大大降低唯一性,因为BIN信息是基于每个银行分配的。已经拥有富裕社区中的小银行发行的帐户的攻击者可以获得一个帐户并使用BIN作为他自己卡上的起点。
校验和数字是使用众所周知的公式计算的,因此可以立即丢弃作为唯一数据源。
在少数BIN值得攻击的情况下,攻击者必须为每个BIN集一次检查9位数字。这是每套10亿的校验和和哈希操作。我没有任何方便的基准测试,但我非常确定每分钟1百万次散列操作对于MD5或任何类型的SHA在适当强大的机器上都是不合理的。在给定的BIN下,这不到一天即可破解所有比赛。
最后,您可以考虑使用哈希值存储时间戳或访问者令牌(IP /子网)。很高兴能够捕获重复的卡号,但也要考虑使用虚假卡号填充系统的人的后果。在某些时候,您需要决定在阻止您知道无效的卡号之间进行权衡,并为自己提供识别和修复误用的机制。
例如,一个心怀不满的员工可能会自己窃取卡信息,然后通过在卡号黑名单中插入有效哈希来阻止重复业务,从而使用您的哈希机制。如果你只是存储一个哈希,那么撤销它是非常昂贵的 - 一旦它被转换为哈希,一切都是不透明的。考虑到这一点,给自己一个方法来识别哈希的来源。
答案 2 :(得分:4)
也许您可以存储两个卡号的不同哈希值。两个哈希值都会导致碰撞的可能性几乎为零。
答案 3 :(得分:3)
使用SHA1,尚未找到哈希冲突。
答案 4 :(得分:3)
人们指出哈希是“破碎”的,但却忽略了这一点,或许他们在不理解其含义的情况下反刍他们所听到的东西。当人们谈论哈希被“破坏”时,他们通常意味着可以轻松生成一个计算相同哈希值的备用有效负载。
这会“打破”散列,但仅限于使用散列来验证数据的特定目的。
这在这里并不重要,即有人设法创建一个备用数据流,其恰好与其中一个信用卡相同,但在攻击向量方面无法实现任何有意义或有用的功能。< / p>
这里的哈希风险是信用卡号码的问题空间非常低,而且彩虹表格相当便宜且易于生成。
添加盐可以为已经生成的纯卡表添加一些保护,但是它提供任何真正保护的程度取决于在您受到损害的情况下盐的保密程度。如果盐被暴露出来,那么新的彩虹表可以便宜地生成,而且一切都结束了。
鉴于应用程序可以使用salt来执行对黑名单的检查,因此很有可能某些危害黑名单数据的人也能够获得盐。如果您有多个服务器,可以通过确保盐和数据不在同一个“位置”来在一定程度上缓解这种情况,因此一台服务器的暴露不会给某人所需的所有部分。 (类似地,对于备份,不要将数据和盐存储在同一个媒体上,有人可以用一条磁带走开并获取所有内容)。盐只是在秘密时才增加一些保护(在这种类型中使用)。
如果你有足够的资源安全地做到这一点,那么我认为这是要走的路。如果您在任何合理的哈希函数上遇到大量冲突,那么您必须执行大量的操作。 (事实上,我很惊讶碰撞即使在那时也会出现问题,任何合理的哈希函数都应该在像这样的小问题空间上提供不同的结果。)
答案 5 :(得分:3)
正如其他人所说,HMAC应该是最佳选择。
带有正确密钥的HMAC-SHA-256应该:
但还有一件非常重要的事情:
您有充足的理由不存储信用卡号码。 即使如果你可以100%确定使用正确的加密,你可能仍然不会存储信用卡号码。为什么?首先,因为密钥可能泄露。
因此您存储哈希值,因此无法检索信用卡号。 ......对吧?
好吧,如果你使用普通哈希,一个简单的彩虹表,其中包含所有可能的信用卡号的哈希值,它会丢弃你可能没有存储的所有原始数据。哎呀。但是你现在知道了。
所以我们努力做得更好。让我们说使用单个盐更好,使用HMAC是我们所知道的最佳方法。
考虑以下情况:
这留下5个数字是暴力强制的。 这是一次微不足道的100次尝试。
如果我们使用了单独的盐,那就结束游戏吧。我们可以简单地对每个单独的卡号进行暴力破解,平均每次尝试50次。
如果我们使用过HMAC,我们似乎是安全的。但请记住......我们选择不存储加密的卡号,因为即使使用完美的加密,密钥也可能泄露。你猜怎么着。我们的HMAC密钥可以泄露相同。再次,使用密钥,我们可以平均强制每个卡号码平均50次尝试。因此,泄露的密钥会为我们提供信用卡号码,就像我们存储加密的卡号一样。
因此,由于信用卡号码的熵较低,与加密值相比,存储哈希值不会增加太多安全性(但PCI将密钥轮换要求限制为加密)。
一点观点:
好的,我们在这里假设泄露的密钥。极端。但话说再说一次,PCI作为他们推理你存储信用卡号码的理由的一部分也是如此,所以我们至少应该考虑它。
没错,我没有考虑多次猜测来找到BIN。不过,这应该是一个小常数。或者我们可以将自己限制在一个BIN。
当然,PCI审核员可能比我更宽容。
是的,如果您没有存储蒙面卡号,那么您的安全系数就会高出10倍。这有很大帮助。使用它对您有利。尽管如此,如果50K尝试是可行的,那么500M也是可行的。在密钥泄露的情况下,这还不足以让我认为数据是安全的。
结论:
使用HMAC-SHA-256。了解风险。尽可能少地存放。警惕地保护你的钥匙。在硬件安全模块上花一大笔钱: - )
答案 6 :(得分:2)
如果您发现与MD5发生冲突,为什么不使用更好的算法,例如SHA1 or SHA256?
答案 7 :(得分:2)
MD5不是要走的路,因为它坏了。引用Bruce Schneier:“[已经知道MD5是一个破坏的哈希函数”并且“不再有人应该使用MD5了。”
即。使用SHA512或SHA256作为已提议的人。
答案 8 :(得分:2)
正如Henri已经提到的那样(+1),正确的解决方案是使用带有密钥的消息认证码,例如HMAC。这正是之前提到过的“秘密盐”。 (顺便说一下。盐总是公开的)。
使用标准结构,如HMAC-SHA-256(RFC2104,FIPS-198a),保密密钥并将结果(认证标签)存储在数据库中。
SHA-256的较大摘要大小(256位)应该可以防止发生任何冲突,SHA-256是一个相当好的散列函数,随机碰撞的概率是2 ^ -128,所以如果你遇到碰撞你的系统,请告诉我! :)
答案 9 :(得分:1)
使用最强的哈希值通常很好。速度并不是本质上的,速度实际上对任何尝试蛮力逆转散列值的人都有效。
我个人喜欢漩涡 - 如果您使用的是PHP,请查看the hash function docs支持的算法
Whirlpool返回一个长度为128个字符的字符串,但您不必将所有字符串存储起来。前32或64个字符就足够了。你也可以考虑使用sha512或sha284。
答案 10 :(得分:1)
不要打扰盐,只需使用HMAC。我知道这是一种滥用,但是你得到了一个不错的键控哈希,所以你可以防止碰撞和彩虹表攻击。
这里的好处是,即使密钥泄漏,也没有人可以解密它。适用于HMAC的最好的事情是蛮力。实际上,这里的关键是如前所述的盐。这里的好处是,算法比大多数非安全程序员通常的腌制方法要好一些。