我正在为一家生产礼品卡代码的公司工作,该代码可用于在线商店支付商品。
我想知道生成这些礼品卡代码最安全的方法是什么。长度需要16个字符(虽然可以协商)并且可以是字母数字(虽然数字会更客户友好)。
从我所看到的,最安全的方法是使用以下Java代码生成特定长度的礼品卡代码:
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static SecureRandom rnd = new SecureRandom();
String randomString( int len ){
StringBuilder sb = new StringBuilder( len );
for( int i = 0; i < len; i++ )
sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
return sb.toString();
}
这取自SO回答here。我从字符串中删除了小写字母,使其更加用户友好。所以这产生了36 ^ 16种组合。单独的数字将是10 ^ 16种组合。我认为只有数字就足够了,但它经常强调,鉴于礼品卡欺诈的流行程度越来越高,字符串应该是字母数字。
那么问题一:数字还是字母数字?
当用户在网上商店使用礼品卡支付商品时,会致电我们的API,该API会返回该礼品卡的余额和货币。鉴于礼品卡代码是在第三方服务器上输入的,现在这些礼品卡可供有权访问这些服务器的人使用。在用户部分兑换之后仍有余额的情况下,这显然是一个问题。
一种选择是,当我们调用我们的API(使用礼品卡代码)以获得余额时,我们返回并在他们的商店中保存一个随机字符串,该字符串只能由在线商店使用向我们开帐单 - 我们会将其与我们系统上的礼品卡代码相匹配。问题可能是用户在结账时输入的礼品卡代码会记录在他们的日志中的某个位置,任何有权访问这些日志的人都可以访问。
另一个选择是我们在部分兑换后刷新礼品卡代码。因此,用户基本上获得了用于余额的新礼品卡代码,并且前一个被取消。这可能是最安全的,但不是那么用户友好。
这就是第二个问题:我们如何确保仅部分兑换的礼品卡代码仍有价值?
答案 0 :(得分:3)
所以你面临的问题是一个有趣的问题。我读了 @ Therac&#39> 解决问题的方法,我不得不同意他最终会创建类似加密货币的协议。我也同意他所有的加密建议。
我不会重复 @ Therac的解决方案,但是,我会看看我是否可以通过解释加密货币的一些想法来提供帮助。我不会详细介绍技术细节,但是在表面层面,你可以自己判断这个想法是否符合你的用例。
因此,大多数加密货币使用的数据结构是Merkle哈希树。我们的想法是将它作为仅附加事务的日志保存,以验证以前的事务,并且它们不会被重复使用。
所以有两种类型的交易。
创建交易仅在signed by your company时才有效。因此,您可以存储您提供的金额,用户的公共地址(可能是他的帐号)和他的礼品卡代码。
第二种交易将是SpendGiftCode。这需要该人的礼品卡代码,并要求他也签署交易以验证交易来自他。
然后,SpendGiftCode完全使用礼品卡代码(破坏礼品卡代码并存储它已经被使用过)并执行以下两项操作之一:giftcardcode
(这是其他方帐号)。giftcardcodes
。一个10美元的发送给另一方,剩余金额的新giftcardcode
被发送回他的账户。这需要为您的用户和供应商创建帐户,但可以帮助缓解双重支出和跟踪等问题。由于它只是一个附加日志,因此您可以跟踪每个供应商和用户所做的事务跟踪。 merkle hash tree允许在日志保留中进行优化。
当然,我没有深入研究几层技术难题,当然我的解释中有一些情节漏洞,因为我试图提供一个广泛的概念。随时可以编辑您可能看到错误的地方。希望这有一些帮助,
干杯!
答案 1 :(得分:1)
考虑将OAuth 2.0协议与JWT一起使用。使用OAuth在商店端对用户进行身份验证,并提供有关令牌中余额的信息。请勿提供任何礼品卡代码或任何重要的个人信息。如果您需要提供礼品代码(供客户调查)生成任何只是为了区分但不使用它们进行身份验证。当用户在线进行交易时,商店需要对其进行身份验证以获得实际余额。
答案 2 :(得分:1)
对于第一个问题(数字或字母数字?) - 如果您专注于安全性(我认为应该是这种情况),那么您希望增加编码字母表的复杂性,以便蛮力/猜测攻击者必须花费更多精力才能发现有效的礼物代码
通过增加可能性的数量,猜测的概率会降低(但它仍然不是防弹)
我建议使用 alpha(区分大小写)+数字
事实上,如果攻击者可以反复尝试猜测您的代码,而不是随机猜测一次性代码
,那么您更关心为了防止这种情况,您可以利用现有的安全机制/概念,例如:
(1)如果(您选择)1-2-3-5优惠券调用失败,您可以引入指数重试延迟,以限制同一源可以在您的API上安装的连续攻击数量
(2)通过http重定向设置验证码机制,以防止机器人在X(您选择的)API命中失败后滥用
同样,因为您在相对较低的数字范围内使用随机函数,所以在将代码授予之前,您需要仔细检查新生成的代码对数据库的唯一性。客户,以避免最终的碰撞,反过来可能会使您的应用程序处于不需要的状态
对于第二个问题,在选择安全机制之前听起来更像是一个商业决策。如果您想保留优惠券服务,您可以向合作伙伴支付全部金额并让他管理余额,或者您可以保留自己系统中现有优惠券的剩余余额,但风险是合作伙伴泄露您的优惠券代码数据这对你来说会是一个更大的问题,或者你也可以发布另一个剩余余额的新优惠券(但是你有挑战将它与一个很容易分散注意力的未知用户联系起来)否则你会必须管理用户财务帐户,这会使您转变为不同的服务..
答案 3 :(得分:1)
我仔细阅读了所有回复并提出了解决方案,并考虑了以下建议:
我们生成一个发送给用户的链接。链接中发送的密钥是一个随机的字母数字字符串,它是经过哈希处理的(MD5或类似的东西),因此在保存到数据库之前不能被激活。
当用户点击链接时,他们会被重定向到我们的目标网页,我们会使用该密钥获取订单,检查订单的状态以及是否有信用卡,以及是否有信用卡。好吧,我们生成一个16个字符长度的字母数字代码并发送到UI。 16个字符的代码经过哈希处理(同样是MD5)并保存在我们的数据库中。每次用户点击链接时,他们都会看到每次动态生成的新礼品卡代码。
在与网上商店的合约中,我们指明他们无法在任何地方登记或保存礼品卡代码(我们的2个客户是大型知名网上零售商)
在我们客户的网上商店结账页面上,用我们的礼品卡代码付款,用户提供16个字符的礼品卡代码。它被发送到我们的服务器和余额和随机支付I.D.返回在线商店。此付款I.D作为订单的一部分保存在在线商店中。订单完成后,在线商店会向我们的服务器发送API请求(带有付款ID)以从礼品卡兑换金额(此功能由我们构建,并通过他们安装的插件提供给在线商店)。
使用OAuth 2.0
如果礼品卡上剩余余额,则会生成新的礼品卡代码(向用户发送新链接以获取余额的新礼品卡代码)
当在线商店向我们收费时,他们会向我们提供付款ID列表,然后我们将其与我们后端的礼品卡代码匹配(然后与我们的发卡行匹配)。
保护:
如果有任何意见,请告诉我。