我正在尝试验证购买时收到的android计费收据的真实性。 验证是在服务器端进行的,但是我在想,如果有时服务器可能已关闭,我可能会从应用程序本身检查签名。
这是我在服务器上验证购买的方式。
<?php
// get data param
$data = $_GET['response'];
// get signature param
$signature = $_GET['signature'];
// get key
$key_64 = "MY Base64 KEY FROM DEVELOPER CONSOLE";
$key = "-----BEGIN PUBLIC KEY-----\n".
chunk_split($key_64, 64,"\n").
'-----END PUBLIC KEY-----';
//using PHP to create an RSA key
$key = openssl_get_publickey($key);
// state whether signature is okay or not
$ok = openssl_verify($data, base64_decode($signature), $key, OPENSSL_ALGO_SHA1);
if ($ok == 1) {
echo "verified";
} elseif ($ok == 0) {
echo "unverified";
} else {
die ("fault, error checking signature");
}
// free the key from memory
openssl_free_key($key);
?>
那么如何在Android上做同样的事情?
答案 0 :(得分:0)
这是使用Android计费库的一种可能方法。您需要从播放控制台中获取应用程序的Base64编码的RSA公共许可证密钥。 here中的说明告诉您如何找到它:
要查找此密钥对的公共密钥部分,请打开您的 在Play控制台中找到该应用程序的详细信息,点击“服务和API”(在开发人员工具下),然后 查看标题为该应用程序的许可证密钥的字段。
现在是方法:
private boolean check_purchase_signature(String json, String signature) {
final String LICENSE_KEY = "LONG_STRING_FROM_THE_PLAY_STORE_CONSOLE";
final String TAG = getApplication().getPackageName(); // or whatever
try {
java.security.Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(
(Base64.decode(LICENSE_KEY,
Base64.DEFAULT)))));
sig.update(json.getBytes());
if (sig.verify(Base64.decode(signature, Base64.DEFAULT))) {
Log.e(TAG, "Signature verification passed.");
return true;
}
} catch (Exception e) {
Log.e(TAG, "Signature verification failed.", e);
}
return false;
}
您可以像这样检查任何购买的签名:
check_purchase_signature(purchase.getOriginalJson(), purchase.getSignature());
请注意,此处的信息最初来自Security class of the ancient IABHelper。它只是归结为一种方法,还没有经过全面测试。
希望这会有所帮助!