Android In app billing - 删除安全类依赖项

时间:2012-08-27 15:21:50

标签: android in-app-purchase in-app-billing

我正在使用In App Billing示例应用将此功能添加到我的应用中。 在我将其添加到我的应用程序并测试完所有工作后,我注意到此Security class中的评论:

  

与安全相关的方法。为了安全实施,全部   此代码应在与之通信的服务器上实现   设备上的应用程序。为了简单起见   此示例的清晰度,此代码包含在此处并执行   在设备上。如果您必须在手机上验证购买,那么您   应该混淆这段代码,使攻击者更难   将代码替换为将所有购买视为已验证的存根。

正如谷歌建议的那样,我在服务器端进行购买验证,所以我真的不需要我项目中的安全类。 问题是,我无法弄清楚如何删除Security类中的BillingService类依赖项。

我首先删除了安全类并关注了BillingService中的错误,并且在大多数地方使用它我可以轻松删除,除了在一个地方:

private void purchaseStateChanged(int startId, String signedData, String signature) {
        ArrayList<Security.VerifiedPurchase> purchases;
        purchases = Security.verifyPurchase(signedData, signature);
        if (purchases == null) {
            return;
        }

        ArrayList<String> notifyList = new ArrayList<String>();
        for (VerifiedPurchase vp : purchases) {
            if (vp.notificationId != null) {
                notifyList.add(vp.notificationId);
            }
            ResponseHandler.purchaseResponse(this, vp.purchaseState, vp.productId,
                    vp.orderId, vp.purchaseTime, vp.developerPayload);
        }
        if (!notifyList.isEmpty()) {
            String[] notifyIds = notifyList.toArray(new String[notifyList.size()]);
            confirmNotifications(startId, notifyIds);
        }
    }

如果有人可以在不使用安全类的情况下分享他/她的purchaseStateChanged方法(基于应用内结算示例应用),那就太喜欢了。

1 个答案:

答案 0 :(得分:1)

所以这就是我所做的。首先,对BillingService的调用发生在应用程序主线程上,因此您需要在后台线程中发出服务器调用。我选择在主线程上完成处理,因为我不确定在后台线程上调用像'confirmNotifications'这样的方法有什么影响。

我创建了一个回调接口VerifyTransactionCompletion,可以在远程调用完成后将其调度回主线程。

我保留了Security类,并让它现在管理对服务器的调用,而不是它最初在示例中执行的操作。因此,当您看到对安全性的调用时,我就会调用我的服务器并执行签名验证。

/**
 * Callback interface to <em>finish</em> processing a transaction once the remote
 * servers have processed it.
 */
public interface VerifyTransactionCompletion {
    public void transactionVerified(List<Security.VerifiedPurchase> purchases);
}

private void purchaseStateChanged(final int startId, String signedData, String signature) {
    // verifyPurchase issues remote call to server (in a background thread), then
    // calls transactionVerified on the main thread to continue processing.
    Security.verifyPurchase(signedData, signature, new VerifyTransactionCompletion() {

        @Override
    public void transactionVerified(List<VerifiedPurchase> purchases) {
            if (purchases == null) {
                return;
            }

            ArrayList<String> notifyList = new ArrayList<String>();
            for (VerifiedPurchase vp : purchases) {
                if (vp.notificationId != null) {
                    notifyList.add(vp.notificationId);
                }
                ResponseHandler.purchaseResponse(BillingService.this, vp.purchaseState, vp.productId,
                        vp.orderId, vp.purchaseTime, vp.developerPayload);
            }
            if (!notifyList.isEmpty()) {
                String[] notifyIds = notifyList.toArray(new String[notifyList.size()]);
                confirmNotifications(startId, notifyIds);
            }
        }

});        

}