android in-app billing v3 api中的开发人员有效负载应该是啥?

Posted

技术标签:

【中文标题】android in-app billing v3 api中的开发人员有效负载应该是啥?【英文标题】:What should be the developer payload in android in-app billing v3 api?android in-app billing v3 api中的开发人员有效负载应该是什么? 【发布时间】:2013-09-07 22:36:00 【问题描述】:

我正在我的应用中实施应用内结算以解锁高级功能。 应用内结算设置正确。除了“开发人员有效负载”之外,一切似乎都很好。

示例应用说明

 /*
     * TODO: verify that the developer payload of the purchase is correct. It will be
     * the same one that you sent when initiating the purchase.
     *
     * WARNING: Locally generating a random string when starting a purchase and
     * verifying it here might seem like a good approach, but this will fail in the
     * case where the user purchases an item on one device and then uses your app on
     * a different device, because on the other device you will not have access to the
     * random string you originally generated.
     *
     * So a good developer payload has these characteristics:
     *
     * 1. If two different users purchase an item, the payload is different between them,
     *    so that one user's purchase can't be replayed to another user.
     *
     * 2. The payload must be such that you can verify it even when the app wasn't the
     *    one who initiated the purchase flow (so that items purchased by the user on
     *    one device work on other devices owned by the user).
     *
     * Using your own server to store and verify developer payloads across app
     * installations is recommended.
     */

示例应用使用空字符串作为开发人员有效负载。我的问题是使用什么字符串作为开发人员有效负载? 我可以使用用户的主电子邮件 ID 吗?

【问题讨论】:

查看此链接:***.com/questions/17196562/…。我希望它能解决您的所有疑问。 谢谢毛利克。链接中的答案真的帮助了我:) 您应该关闭您的问题或在下面纠正我的答案以使问题得到解决,以便其他人可以根据需要检查此问题。 【参考方案1】:

对我来说,随机字符串首先没有用,它需要依赖于购买它的用户,而不是购买它的设备。其次,它是非消耗品,因此空字符串可能适合,但并不理想。

所以我的解决方法是根据密钥创建加密哈希。每次购买时,它都是唯一可识别的,因为哈希值永远不会相同(这取决于哈希方法,例如 bcrypt)。

由于所有设备上的密钥都相同,因此很容易解密并验证秘密消息是否正确。

为了让密钥保密,我使用了各种字符串操作函数来屏蔽它,这样它就不会以可见的方式存储。

可以在此处找到文本处理的示例:android In App Billing: securing application public key

String Base64EncodedPublicKey key = DecrementEachletter("Bl4kgle") + GetMiddleBit() + ReverseString("D349824");

这种基于密钥创建哈希的方法允许有效负载是唯一且可识别的,同时具有相当的安全性。它不是防弹的,但确实很难破解。

【讨论】:

你如何用这种方法识别用户? @Renjith,你不知道。这种方法是为了识别购买是否合法。 请我不明白,相同输入的唯一有效载荷如何?密钥始终相同。来自相同输入的哈希返回相同的结果。 @t0m 这取决于所使用的散列方法。 Bcrypt 允许你使用相同的字符串得到不同的哈希结果。【参考方案2】:

请检查以下答案,它可能会解决您的问题:

如果您使用的是消耗品(被管理的物品),那么您可以使用随机生成的字符串

第 1 步:在创建方法之前声明:

         private static final char[] symbols = new char[36];

                static 
                    for (int idx = 0; idx < 10; ++idx)
                        symbols[idx] = (char) ('0' + idx);
                    for (int idx = 10; idx < 36; ++idx)
                        symbols[idx] = (char) ('a' + idx - 10);
                

第 2 步:在您的活动中设置 RandomString 和 SessionIdentifierGenerator 类

          public class RandomString 

        /*
         * static  for (int idx = 0; idx < 10; ++idx) symbols[idx] = (char)
         * ('0' + idx); for (int idx = 10; idx < 36; ++idx) symbols[idx] =
         * (char) ('a' + idx - 10); 
         */

        private final Random random = new Random();

        private final char[] buf;

        public RandomString(int length) 
            if (length < 1)
                throw new IllegalArgumentException("length < 1: " + length);
            buf = new char[length];
        

        public String nextString() 
            for (int idx = 0; idx < buf.length; ++idx)
                buf[idx] = symbols[random.nextInt(symbols.length)];
            return new String(buf);
        

    

    public final class SessionIdentifierGenerator 

        private SecureRandom random = new SecureRandom();

        public String nextSessionId() 
            return new BigInteger(130, random).toString(32);
        

    

第 3 步:将有效负载传递到您的购买请求中:

RandomString randomString = new RandomString(36);
            System.out.println("RandomString>>>>" + randomString.nextString());
            /* String payload = ""; */
            // bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ
            String payload = randomString.nextString();
            Log.e("Random generated Payload", ">>>>>" + payload);

        Log.d(TAG, "Launching purchase flow for infinite gas subscription.");
            mHelper.launchPurchaseFlow(this, SKU_GAS,
                    IabHelper.ITEM_TYPE_INAPP, RC_REQUEST,
                    mPurchaseFinishedListener, payload);

有关更多信息,请查看此链接: Token that identify the user

希望它能解决你的问题。

【讨论】:

不要使用随机字符串。用户可以在一台设备上购买商品并希望在另一台设备上拥有它。这一点在 questing (2nd item) 中有描述 取消购买再尝试购买也是一个问题。 Google Play 每次都会返回第一个有效载荷。 @mlatu developer.android.com/training/in-app-billing/… 请查看谷歌网站。我们必须将开发人员有效负载存储在我们自己的 Web 服务器中,以便特定用户摆脱设备问题。 @defhlt 我认为它已经附加到您用来完成购买的 gmail 帐户。为什么有效载荷很重要?

以上是关于android in-app billing v3 api中的开发人员有效负载应该是啥?的主要内容,如果未能解决你的问题,请参考以下文章

android in-app billing v3 api中的开发人员有效负载应该是啥?

In-App Billing v3 - 不检测退款

In-App Billing v3 可靠性缺陷

Android In-App Billing:订单取消后购买状态保持“已购买”

SDK接入之Android Google Play内支付(in-app Billing)接入

如何使用 Java (Servlet) 验证来自 In-App Billing Android Market 的签名数据