如何使用旧的订单ID格式在本地validationGoogle收据validation?

我想validationGoogle收据validation,但由于我没有客户端密钥, 因此无法使用Google API : https : //developers.google.com/android-publisher/archive/v1_1/inapppurchases/get

所以我通过使用public keysignedDatasignature来进行本地validation。

一切正常,因为我有新的orderId与格式:

GPA.XXXX-XXXX-XXXX-XXXXX

但是,这段代码不适用于旧模式orderId ,如下所示:

 4582257046313445026.7467948335710411 

我得到例外:

签名exceptionjava.security.SignatureException:签名长度不正确:得到294,但期待256

所以我成功的生成了PublicKey bu, verify失败:

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

我知道RSA签名应该是256,在我的情况下我得到了294

参考: Google Play订单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); } } 

任何想法如何validation它?

如果你有解决scheme,不pipe用什么语言Clojure,Skala,Ruby,Java ……

Solutions Collecting From Web of "如何使用旧的订单ID格式在本地validationGoogle收据validation?"

假设你正试图validation一些真实的收据:如果你得到SignatureException – 这意味着没有别的,但给定的签名是无效的 。 而你的代码必须相应地处理这样的签名,

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

你已经请求了一些与旧式orderId相关的代码: 在这里你去 。 如您所见,Ruby中的validation部分与您的validation部分非常相似。 再一次,你的validation码没有问题。 问题特别在于收据签名本身。

现在, 为什么你有无效的签名的答案。 你并不孤单,看到无效的签名进来,特别是对于旧格式的订单id,就像在这里 (以及在那里和在任何地方 )所提到的那样,在Google切换到新的GPA前缀ID之后即将到来。 顺便说一句,你可以仔细检查你有相同的条件如下:

在GooglePlay控制台的“订单pipe理”选项卡中searchorderIds将不会返回这些orderIds的结果。

从逻辑上来讲,最根本的原因就是欺诈行为 。 看看这个答案 ,例如如何欺诈stream量可以看起来像

回到你的问题如何使用旧的订单ID在本地validation收据 – validation它与新的订单ID一样的方式(如你已经这样做),并考虑签署不正确的长度作为一个是无效的。