充值系列——充值系统安全问题(四)

这是充值系列的最后一篇,将讨论充值安全的问题。正如这个系列的其他文章提到的,充值系统的流程如下:

充值系列——充值系统安全问题(四)_第1张图片

注意: 4,5执行顺序不确定,步骤4是支付平台自动向服务器请求,步骤5是玩家点击“返回商家网站”时支付平台请求服务器,如果玩家不点击,这可能不会触发,所以这是一个不可靠的请求。

支付的安全问题主要发生在步骤3和4中。下面是详细说明:

在步骤3中,客户端需要把订单信息提交给支付平台,比如玩家购买100个金币,他需要支付人民币10元。订单信息如下:

{

 "product_name" : 100金币,

 "total_fee" 100, 

 "currency": RMB

}

当玩家点击提交订单的时候,会把这个订单信息提交到支付平台,如果有人劫持这个请求,并且把订单信息的总费用修改为0.1元,那么支付平台只会扣除玩家0.1元,同时,这笔订单会顺利完成。也就是玩家只花了0.1元购买了原来100元的商品。

在步骤4中,支付平台会把订单处理结果和订单信息返回给服务器,例如返回的结果如下:

{

 "status" : "fail"  // 表示支付失败

 "product_name" : 100金币,

 "total_fee" 100, 

 "currency": RMB

}

这里,如果某个玩家把这个URL劫持,并且修改其中的某些信息,例如把支付失败改为支付成功,或者自己拼接一个URL向游戏服务器发起请求,那后果可想而知。我们需要保证订单除了结果没有被修改,同时还要保证这个请求来自于支付宝。

针对串改订单信息的问题,支付宝的做法是使用RSA算法加密订单信息,对于步骤4中发生的问题,支付宝要求服务器验证请求是否来自于支付宝,同时验证返回的订单信息,如订单信息是否被串改,支付状态是否为成功等。

RSA加密的思路: 把订单信息和商户私钥加密。同时把这个签名传给支付宝。只要不泄露商户私钥,订单信息基本上不可能会被串改。当然,服务器也会验证订单信息没有被修改。

服务器端验证订单信息是否被修改: 

第一步:服务器端会接收到从支付宝返回过来的订单信息和之前签名的结果,这个时候,服务器在把订单信息签名,同时和之前的签名结果对比,如果一致,说明订单信息没有被修改。

第二步:获取支付宝返回的数据之一notify_id,按照支付宝要求的格式拼接成URL,提交给支付宝,如果返回为true,则说明这请求确实来自于支付宝。如果所示:

充值系列——充值系统安全问题(四)_第2张图片

做支付系统的一些思考:

1:在做游戏后台的时候,需要经常向游戏服务器请求数据,这里就有一个安全问题,游戏服务器如何信任这个请求呢,这里就可以参考支付宝的签名机制:把需要向游戏服务器请求的数据和一个”密文“生成一个签名,把这个签名也提交给游戏服务器,当游戏服务器接受到请求后,再把请求的数据和”密文“加密,同时把结果和接受到的签名比对,这样就可以判断这个URL的合法性了。

2:支付平台接入都大同小异,关键是要理解支付的流程,更深入支付流程的规范性和安全性,这对以后的编程也很有帮助。

3:在接入360,91这样的平台的时候,需要理解oauth2.0,也涉及到URL请求合法性的问题,但是Oauth2.0和本篇文章的做法不同。下一篇文章,将讨论一下oauth2.0的应用。


充值系列—充值系统数据库设计(一)

充值系列——充值系统的架构(二)

充值系列——充值系统业务逻辑层实现(三)




你可能感兴趣的:(PHP,游戏设计与实现)