当前位置: 首页 > 知识库问答 >
问题:

如何用旧订单ID格式在本地验证谷歌收据验证?

栾弘新
2023-03-14
4582257046313445026.7467948335710411

我得到例外:

签名异常java.security.signatureException:签名长度不正确:得到294,但预期为256

因此,我成功地生成了publickeybu在verify:

sig.verify(Base64.decode(signature, Base64.DEFAULT) // <- java.security.SignatureException

参考:谷歌播放订单ID更新为新格式

String base64PublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3dkBTr2pD2YSqSK2ewlEWwH9Llu0iA4PkwgVOyNRxOsHfrOlqi0Cm51qdNS0aqh/SMZkuQTAroqH3pAr9gVFOiejKRw+ymTaL5wB9+5n1mAbdeO2tv2FDsbawDvp7u6fIBejYt7Dtmih+kcu707fEO58HZWqgzx9qSHmrkMZr6yvHCtAhdBLwSBBjyhPHy7RAwKA+PE+HYVV2UNb5urqIZ9eI1dAv3RHX/xxHVHRJcjnTyMAqBmfFM+o31tp8/1CxGIazVN6HpVk8Qi2uqSS5HdKUu6VnIK8VuAHQbXQn4bG6GXx5Tp0SX1fKrejo7hupNUCgOlqsYHFYxsRkEOi0QIDAQAB";
String signedData = "{\"orderId\":\"GPA.3353-8027-5082-45637\",\"packageName\":\"com.mycompany.testapp\",\"productId\":\"weekly\",\"purchaseTime\":1503578932746,\"purchaseState\":0,\"developerPayload\":\"1502364785372-5918650324956818356\",\"purchaseToken\":\"bfljoelddlibhbibhnbnflej.AO-J1Oz8pvdqCmzz04OBmegRVKEG1stj4su5HH4uc-gzsz_vlhcz7iB_NUZVBNXp3RlTGyIGnsIgOe6bqvqfUIbPC9_CrCngL0EkZp-SBwaRzfn-EgJ32yQ\",\"autoRenewing\":true}";
String signature = "TyVJfHg8OAoW7W4wuJtS4dM//zmyECiNzWa8wuVrXyDOCPirHqxjpNthq23lmAZlxbTXyMNwedMQPr9R8NJtp3VTzGuNlLYBSOERVehmgstXiiwWDBvTNzgWbwimZmFaIiCExMQiPvbXHoWQh2rClFeAd4FfdC15pNf3NqfOGhUAEmieeb572umOo4YoF0l0421pY/JWYXa+2dtO6pcnSHF6gidRDXR66s/enRZUvkB4x9CEHdA862LDKbwOG4Aihh03IRLjD+m/5WNW+w05Q8bNNA6sCzFGVD+qa3IDiSqkiISCpd3UnufePxf3+O2doWjg2mXC5agEDMnNXvhfrw==";


boolean result = DefaultSignatureValidator.validate(base64PublicKey, signedData, signature); 

DefaultSignatureValidator.class:

public class DefaultSignatureValidator {

        protected static final String KEY_FACTORY_ALGORITHM = "RSA";
        protected 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
         */
        protected static PublicKey generatePublicKey(String encodedPublicKey) {
            try {
                byte[] decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT);
                KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
                return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            } catch (InvalidKeySpecException e) {
                System.out.println("Invalid key specification.");
                throw new IllegalArgumentException(e);
            } catch (Exception e) {
                System.out.println("Base64 decoding failed.");
                throw new IllegalArgumentException(e);
            }
        }

        protected static boolean validate(PublicKey publicKey, String signedData, String signature) {
            Signature sig;
            try {
                sig = Signature.getInstance(SIGNATURE_ALGORITHM);
                sig.initVerify(publicKey);
                sig.update(signedData.getBytes());
                if (!sig.verify(Base64.decode(signature, Base64.DEFAULT))) {
                    System.out.println("Signature verification failed.");
                    return false;
                }
                return true;
            } catch (NoSuchAlgorithmException e) {
                System.out.println("NoSuchAlgorithmException" + e);
            } catch (InvalidKeyException e) {
                System.out.println("Invalid key specification" + e);
            } catch (SignatureException e) {
                System.out.println("Signature exception" + e);
            } catch (Exception e) {
                System.out.println("Base64 decoding failed" + e);
            }
            return false;
        }

        public static boolean validate(String base64PublicKey, String signedData, String signature) {

            PublicKey key = DefaultSignatureValidator.generatePublicKey(base64PublicKey);
            return DefaultSignatureValidator.validate(key, signedData, signature);
        }
}

有什么想法如何验证它吗?

共有1个答案

支华池
2023-03-14

假设您试图验证某个真实的收据:如果您得到SignatureException-这意味着除了给定的签名无效之外,没有其他任何东西。您的代码必须相应地处理此类签名,即。

...
} catch (SignatureException e) {
    return false;
} 
...

您已经请求了一些与处理旧样式的OrderID相关的代码:现在开始吧。正如您所看到的,Ruby中的验证部分与您的验证部分非常相似。同样,您的验证代码段没有问题。问题在于收据签名本身。

现在,关于为什么你有无效签名的答案。你并不是唯一一个看到无效签名的人,尤其是对于旧格式的订单ID,比如在这里(还有那里和到处),它们是在谷歌切换到新的以GPA为前缀的ID后很久才出现的。顺便说一句,您可以重复检查您是否具有以下相同的条件:

回到关于如何用旧订单id本地验证收据的问题--用与新订单id完全相同的方式验证它(就像您已经做的那样),并将长度不正确的签名视为无效的签名。

 类似资料:
  • 我正在遵循官方的Google身份验证流程。我的应用程序已经使用了最新版本的Google地图。 项目 应用程序 地图下方有一条红线,弹出窗口显示找到了11.8.0和11.4.2。构建错误消息如下:, 错误:任务“:应用程序:进程”的执行失败。 请通过更新谷歌服务插件的版本来修复版本冲突(有关最新版本的信息,请访问https://bintray.com/android/android-tools/co

  • 我有一个可以在本地服务器(而不是谷歌云服务器)上运行的Spring启动应用程序。我计划使用服务号来允许应用程序使用谷歌云存储和日志记录。我创建了一个服务号和一个api密钥,并下载了如下所示的json文件: 如果我在开发环境中启动应用程序,并设置一个指向json文件的环境变量,应用程序就会按预期工作(GOOGLE\u APPLICATION\u凭据)。 但是,我需要在ubuntu中将应用程序作为in

  • 我正在尝试升级我的MVC网站以使用新的OpenID Connect标准。OWIN中间件似乎非常健壮,但不幸的是只支持“form_post”响应类型。这意味着Google不兼容,因为它在“#”之后返回url中的所有令牌,因此它们永远不会到达服务器,也永远不会触发中间件。 我自己尝试过在中间件中触发响应处理程序,但似乎根本不起作用,所以我有一个简单的javascript文件,它解析出返回的声明,并将它

  • 我正在构建谷歌应用程序脚本产品,当我部署GAS项目时,我只想让我的组织中的人可以访问该应用程序。当用户已经用我的组织电子邮件登录时,浏览器就可以了。但是我如何通过邮递员或终端访问部署的URL,我需要访问令牌或其他东西吗?欢迎提供任何建议! 欢迎提供任何建议!

  • 请帮帮我! 我到处找,但还是不明白。 我有域domain1.com,我想访问我的项目-快速启动-111111的“https://www.googleapis.com/auth/spreadsheetshttps://www.googleapis.com/auth/drive”范围。 我已经添加了我的域名,并通过DNS TXT记录进行验证 问题是为什么谷歌说“应用程序未验证”。我在哪里可以验证它?

  • 接下来,我生成了自己的OAuth2客户机ID并使用它。这种方法很简单,直到我开始收到来自Google的“匿名使用过期”错误,一段时间后我意识到这是因为密钥没有启用只读日历范围。 我的下一个想法是公开日历,并使用静态API密钥,但日历是从一个名为Peak Pro的预订服务中同步的,该服务用参加活动的客户的姓名、电子邮件和电话号码填充日历描述。我不能公开揭露那些。 接下来,我被吸引到了CalDAV A