Android应用内结算验证

lwi*_*man 8 security android in-app-purchase

如果我将验证卸载到远程服务器,我认为该过程将是这样的:

Android Market                  Application     Remote Server
       |--------IN_APP_NOTIFY------->|                |
       |                             |-----nonce----->|
       |                             |<----nonce------|
       |<-GET_PURCHASE_STATE_CHANGED-|                |
       |---PURCHASE_STATE_CHANGED--->|                |
       |                             |--verification->|
       |                             |<-verification--|
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,那么nonce就是减少重放攻击漏洞,验证是为了减少欺骗漏洞.此外,文档建议卸载安全处理的原因是验证步骤需要访问我的公共Android Market发布者密钥,远程服务器的目标是保持所述密钥不需要在我的代码中包含/计算.

第一个问题,远程服务器是否有安全原因进行nonce生成/检查?按下验证步骤正确完成,我们会从远程服务器中发现消息是否被欺骗.所以在我看来,nonce就是在那里检测某人转播IN_APP_NOTIFY.

第二个问题,为什么我们的公钥是文字字符串?文档说,"你不想让黑客或恶意用户轻易用另一个密钥替换公钥." 我不清楚有人可以利用我的应用程序,即使他们可以编辑二进制文件以包含恶意公钥而无需重新签名应用程序.

第三个问题,我是否会尝试从远程服务器验证验证时遇到所有这些问题(例如,将公钥存储到应用程序中的远程服务器)?

第四个问题,如果我想将这个购买验证的结果存储在手机上,那么所有这些额外的安全性都是徒劳的(即,我不想在用户访问内容时验证解锁内容的购买状态) ?

小智 10

第一个问题,远程服务器是否有安全原因进行nonce生成/检查?

是的,服务器应生成现时,并进行检查.作为一般规则,几乎所有与安全相关的事情都应该在服务器中完成.随机数是"仅使用一次的数字".所以,服务器的正确之处是:

  1. 生成并保存一个随机数.
  2. 得到答案.
    • 如果答案包含已保存的随机数,请检查签名并进行处理.删除NONCE.
    • 如果答案包含未保存的随机数,则很可能是伪造的/复制的,因此丢弃.

第二个问题,为什么我们的公钥是文字字符串?

如果您对应用程序执行安全检查,那么如果您在服务器上进行工作则完全无关紧要(如您所愿).

如果您在应用程序中执行安全性,则可以通过黑客攻击来绕过安全性.一种技术是更改公钥,如果将其保存为单个字符串则更容易.

第三个问题,我是否会尝试从远程服务器验证验证时遇到所有这些问题(例如,将公钥存储到应用程序中的远程服务器)?

不,你不会.没有人可以访问/更改服务器的代码.至少和应用程序中的"容易"一样.

第四个问题,如果我想将这个购买验证的结果存储在手机上,那么所有这些额外的安全性都是徒劳的(即,我不想在用户访问内容时验证解锁内容的购买状态) ?

这得看情况.

实现具有服务器的应用内购买的"最安全"方式意味着:

  • 您将"可购买"内容保存在服务器中.如果用户购买它,您将其下载到应用程序,并以某种方式保存它很难"复制"到另一部手机.
  • 从服务器,只有在验证过程在服务器中正确完成时才发送内容.
  • 从应用程序中,如果您没有检测到"已保存"内容,请执行"恢复事务"操作,然后从服务器下载所需的所有内容.
  • 谷歌播放的应用内购买并非旨在轻松提供内容,它旨在从集中式网站执行购买,因此,更容易为用户.我们的开发人员最终完成了很多工作来使用它.