防止使用同一张信用卡多次购买?

Posted

技术标签:

【中文标题】防止使用同一张信用卡多次购买?【英文标题】:Prevent multiple purchases with the same credit card? 【发布时间】:2012-02-26 11:38:40 【问题描述】:

我正在考虑如何在我的 Rails 应用程序上开发一个验证程序,该验证程序本质上是检查以确保任何用户用于任何给定交易的信用卡在我们的系统中是唯一的,这样所有信用卡都可以用于为所有用户在整个应用程序中仅购买一件商品一次

此限制背后的想法是,此应用有时会运行对时间敏感的促销交易,我们希望尽最大努力为这些交易建立“一张信用卡购买”系统。

我正在考虑对信用卡号进行哈希处理,然后将该哈希存储在数据库中,然后在每次新购买时交叉引用它(所以我的支付网关保留实际数字,我只保留一个哈希数据库),但on further research, this seems like a bad idea。

所以我回到了绘图板并寻找新的想法。任何人都知道解决这个问题的好方法,同时尽可能保持 PCI 兼容?

我正在使用 Rails 3 进行开发,并使用 ActiveMerchant 与我的支付网关 Authorize.net 集成,如果这有帮助的话。

【问题讨论】:

【参考方案1】:

如果您想要“每个用户一次购买”系统,那么您为什么不在用户尝试购买特价商品时检查他们的购买历史以确保他们之前没有购买过呢?

【讨论】:

因为我还想确保另一个用户不使用第一个用户使用的同一张卡。所以我想这更像是“每张信用卡一次购买”而不是“每个用户”......【参考方案2】:

用户可以注册多个帐户。

尽管通过检查用户历史记录,以及为每次购买强制每个地址购买 1 件商品 - 你可能会没事 - 你也可以通过用户姓名/生日/任何其他识别信息来限制事情。

顺便说一句,信用卡信息也可以更改-实际上购买 100 张具有唯一编号的礼品信用卡非常容易,因此,如果您想将事情细化到最细微的程度...我认为您将无法做到只需抄送号码

【讨论】:

关于礼品信用卡的要点;我没有想到这一点。我还记录了用户的 IP 地址(我知道它也可能被欺骗),但我希望 IP 与散列的 CC 编号相结合可能足以阻止 90% 的规避尝试。 如果可以避免的话,不要散列完整的#。不要让自己成为不必要的目标。 坦率地说,我宁愿不散列完整的#...但我确实需要一种可靠的方法来防止在从外部网站购买商品时多次使用卡。如果我不使用散列 #,我还能使用什么?【参考方案3】:

当然,一些散列是一个坏主意 - 要么是因为它的安全性低,有一些拦截,要么是因为彩虹表很常用。这并不意味着所有散列都是一个坏主意 - 交叉引用的唯一方法将是某种唯一且可预测地识别信息的方法。除非 PCI 明确禁止它 - 散列仍然是要走的路。

确保对哈希进行加盐 - 这可以防止彩虹攻击,或者至少需要彩虹攻击者在构建表时考虑到你的盐。特别是如果您可以使盐保持合理的安全我之所以说只是合理是因为要生成盐,您需要有盐,这意味着它会在某处的代码中。

选择一个好的算法

虽然 MD5 现在声名狼藉,并且以各种语言实现,但它也很常见,您可以找到预制的彩虹表。生成哈希也非常快。您的系统可能可以容忍少量延迟,并使用更多处理器密集型哈希。这使得生成彩虹表的成本更加昂贵。以Tiger algorithm 为例。

多次散列

如果您有多个相关的数据点,那么多个哈希将使进行彩虹攻击变得更加困难。例如: Hash(Hash(Card#+salt1)+expireDate+salt2) - 需要知道卡号和生成日期(对您来说很容易),但不容易逆向工程(彩虹需要每张卡# * 每个有用的过期日期 + 两种盐的知识)。

编辑:(你的 cmets)

相当安全:仅通过加密连接(SFTP、SSH)传输它,不要以未加密的方式存储它 - 包括实时/迭代和备份副本,将带有盐的文件保存在网络树(不能直接访问/意外释放),确保文件的权限尽可能限制(不允许组/全局文件访问)。

动态盐将随机值放入哈希中非常适合减少彩虹攻击 - 您将随机部分与哈希值一起存储在表中 - 现在在构建彩虹时,您必须为每个动态盐。但是,根据您的需要,您不能这样做 - 您需要知道第二次创建哈希时使用的正确随机盐(否则您将永远不会在第二次使用卡时得到拦截)......为此可预测/可重复然后您必须将动态盐基于数字的某些部分......这实际上是与另一个数据点的多重散列所做的。您拥有的数据点越多,您可以在这个方向上散列的越多 - 例如,如果您有 CVV(3 个散列),或者您一次散列 8 个数字(总共 3 个散列:hash(hash(hash(1..8+salt1)+9..16+salt2)+expDate+salt3))。

Best Hash 这是一个移动的目标,但有一个很好的 discussion on security.stackexchange。哪个指向 SHA-512。

【讨论】:

好点,尽管我仍然不确定我的盐在我的代码中的“合理安全性”程度。我链接到的 PDF 建议使用动态盐,但我觉得这会使验证真实性变得更加困难。你对 BCrypt 而不是 MD5 有什么看法?我完全承认我对密码学还不是很了解...... 感谢您提供额外信息;非常有帮助。我试图弄清楚哪种散列最能保护我们的客户数据和我们的业务;立即阅读合规指南 (pcisecuritystandards.org/documents/…)。您认为通过 SHA-512 使用安全盐对最后 4 位数字 + CVV 代码进行散列是一种好方法吗?这会在所有卡中都是唯一的,还是会出现卡的最后 4 位数字和 CVV 代码相同的情况? 据我所知,从未存储过散列、加密、放在拉链驱动器上并隐藏在内衣抽屉或其他任何地方的 CVV。 @Webjedi 公平点;反正觉得很臭。 :) 现在我得清理我内衣抽屉里所有的拉链了…… 最后 4 位数字完全没用 - 很容易而且经常在卡片之间重复。如果 CVV 是这种情况,那么让我们忽略这些 ;)【参考方案4】:

我认为你的方向是错误的。我只会检查最后 4 个卡、IP 和送货地址。如果少数用户玩弄最后一个 4 & ip 解决方案,则存储该数据的风险与损害是不值得的。 (他说不知道购买的性质。)

由于未收集地址...前 4 位、后 4 位和 4 位到期(当然都是散列)应该提供您需要的唯一性,以确保该卡只使用一次。

【讨论】:

我在这里挂断只使用最后四位数字是因为它很容易欺骗 IP 地址并且一遍又一遍地使用同一张卡,即使不更改送货地址。我同意我希望将存储这些数据的风险降到最低,但我需要一个好的替代方案来合理地保证该卡不能被多次使用,除非我付出巨大努力来规避我最终采用的任何解决方案。 这就是为什么我说不知道物品的价值。为了折扣而欺骗 IP 地址通常是不值得的。检查送货地址...每个地址只有一件商品,前 3-5 个街道字符 + zip,最后 4 个字符和 ip,应该达到 95% + 范围。 在我们的案例中,我们曾经有过用户通过欺骗他们的 IP 来玩弄系统的实例——这个数字足以确保不会再次成为问题,这给我带来了考虑检查散列#s。我们的问题更加复杂,因为我们 90% 的产品都不需要送货地址,因此使用它也不是一个真正的选择(产品是数字的)。 可以对帐单地址执行相同操作...前 3-5 个字符 + zip + 最后 4 个字符的哈希值 + 他们的 UserAgent 字符串的哈希值...他们可以切换浏览器,但如果他们偷偷摸摸,那可能会限制为 2 次购买。无论如何,帐单地址在技术上会比卡更好,因为他们可能会为不同的卡使用相同的地址。 最后 4 的哈希值 + zip 的哈希值(假设您使用它进行验证,如果不是我会打开它)我认为必须覆盖 99%。正确的?不过,这只会阻止每张卡购买 1 次……添加帐单地址可能会将其限制为个人。只是我的 2 美分。【参考方案5】:

伪造你的真实credit card number online 是防止这种情况发生的最好方法。花旗银行客户可以登录并使用所有账户提供的此工具。只需生成一个数字和有效期以供在线使用,现在一切都很好。

【讨论】:

以上是关于防止使用同一张信用卡多次购买?的主要内容,如果未能解决你的问题,请参考以下文章

将信用卡读卡器连接到 Web 应用程序?

使用 PayPal 在线订票:防止多个访客购买同一张票

对于信用证的一笔到单,是不是允许多次付款?付款方式与当初信用证开立时候约定的付款方式是啥关系?

防止重复使用信用卡的最佳方法

仅使用 Authorize.Net:对单个信用卡收费授权进行多次部分捕获

如何防止亚马逊账户关联