android - 签名验证,Android in app billing 在之前工作后失败

标签 android in-app-billing

背景:

我们有一个 Android 应用程序目前正在通过 Google Play 销售。为了使应用程序正常运行,用户必须通过应用程序内结算购买“ token ”。 “ token ”是消耗品,例如用一次就用完。为了验证 token ,我们将购买数据发送到服务器,该服务器使用标准 Java RSA 安全代码来验证从 Play 商店返回的信息是否有效。 (下面的代码)。 我们在发布应用程序之前进行了广泛的测试,甚至在应用程序上架后,我们还进行了更多测试。 Google返回的数据每次都通过验证。然后大约在 12 月初,签名验证开始失败。我们没有更改商店中的代码和应用程​​序,服务器上的验证码保持不变。

我已经调试了代码,并运行了从 Play 商店返回的收据数据和签名数据,现在确实无法通过验证。我无法解释发生了什么变化,或者为什么验证在工作正常时开始失败。

问题:

有没有人遇到过这种情况,即在未更改的应用程序中签名验证失败?关于从哪里开始寻找并找出问题可能出处的任何提示?

更多信息

我唯一能想到的改变是 Google 发布了应用内结算 API v3,但这不应该影响我们使用的 V2。

为了帮助开发,我们使用 net.robotmedia.billing 库来处理 IAB。

下面是Play Store返回数据的服务器验证码

其中 encodePublicKey => 我们来自 Play 商店的公钥

signedData => base64 编码的 receiptData 作为 Play 商店购买的返回

签名 => 从 Play 商店返回的签名

public class Security {

    public final static Logger logger = Logger.getLogger(Security.class.getName());

    private static final String KEY_FACTORY_ALGORITHM = "RSA";
    private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";

    /**
     * Generates a PublicKey instance from a string containing the
     * Base64-encoded public key.
     * 
     * @param encodedPublicKey
     *            Base64-encoded public key
     * @throws IllegalArgumentException
     *             if encodedPublicKey is invalid
     */
    public static PublicKey generatePublicKey(String encodedPublicKey) {
        try {
            byte[] decodedKey = Base64.decode(encodedPublicKey);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
            return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        catch (InvalidKeySpecException e) {
            logger.error("Invalid key specification.", e);
            throw new IllegalArgumentException(e);
        }
        catch (Base64DecoderException e) {
            logger.error("Base64 decoding failed.", e);
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Verifies that the signature from the server matches the computed
     * signature on the data. Returns true if the data is correctly signed.
     * 
     * @param publicKey
     *            public key associated with the developer account
     * @param signedData
     *            signed data from server
     * @param signature
     *            server signature
     * @return true if the data and signature match
     */
    public static boolean verify(PublicKey publicKey, String signedData, String signature) {
        Signature sig;
        try {
            sig = Signature.getInstance(SIGNATURE_ALGORITHM);
            sig.initVerify(publicKey);
            sig.update(signedData.getBytes());
            byte[] decodedSig = Base64.decode(signature);
            if (!sig.verify(decodedSig)) {
                logger.error("Signature verification failed.");
                return false;
            }
            return true;
        }
        catch (NoSuchAlgorithmException e) {
            logger.error("NoSuchAlgorithmException.");
        }
        catch (InvalidKeyException e) {
            logger.error("Invalid key specification.");
        }
        catch (SignatureException e) {
            logger.error("Signature exception.");
        }
        catch (Base64DecoderException e) {
            logger.error("Base64 decoding failed.");
        }
        return false;
    }

}

最佳答案

对我来说,也许文件编码是个问题, 更改eclipse工作区后,又使用mac文件格式。

将其更改为 UTF-8 并将 key 再次复制并粘贴到项目中,

现在一切正常:/ 浪费时间:/

关于android - 签名验证,Android in app billing 在之前工作后失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14558116/

相关文章:

java - Json 响应未打印

java - 相同的字符串不同

android - 删除并重新安装应用程序后如何查看购买历史记录

android - getPurchases() NullPointerException 初始化 mService

android - 无法通过 php 服务器验证 android inapp 计费

java - 解析 Twitter API 1.1 JSON

java - 从字节流创建图像的最快方法是什么?

android - 检查android购买状态但返回未找到购买 token

Android:购买后消费产品(应用内计费)

android - 使用 Google 和 Facebook 身份验证在 android 中进行应用内购买(IAP)?