比较签名数据和RSA签名

时间:2019-01-29 05:03:47

标签: php android android-inapp-purchase

我正在尝试验证购买时收到的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上做同样的事情?

1 个答案:

答案 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。它只是归结为一种方法,还没有经过全面测试。

希望这会有所帮助!