简体   繁体   English

Android - 通过服务器端验证保护应用内购买

[英]Android - protecting in app purchases with server side verification

I'm new to android development but created an app and I implemented in-app purchase to remove ads from the app.我是 android 开发的新手,但创建了一个应用程序,我实现了应用程序内购买以从应用程序中删除广告。 I just did a very basic implementation and I basically check if the user has purchased the "no_ads" item and if it's true, then no ads are shown.我只是做了一个非常基本的实现,我基本上检查用户是否购买了“no_ads”项目,如果是真的,则不显示任何广告。 The problem is that I see a lot of "purchases" bein logged on firebase and nothing on play console, which means of course that my users are using those hacking apps.问题是我看到很多“购买”都登录在 firebase 上,而在 play 控制台上什么也没有,这当然意味着我的用户正在使用这些黑客应用程序。 So my question is, how to protect/verify those purchases agains a server so these haking apps are useless?所以我的问题是,如何在服务器上保护/验证这些购买,使这些黑客应用程序无用? I already have a server that my app uses, so there's no problem about implementing any server side code for me.我已经有一个我的应用程序使用的服务器,所以为我实现任何服务器端代码都没有问题。 It would be great if someone could point me to a tutorial.如果有人能给我指点教程,那就太好了。 Thanks谢谢

My small contribution to reduce fraud in in-app purchases我对减少应用内购买欺诈的小贡献

Signature verification on an external server, on your Android code :外部服务器上的签名验证,在您的 Android 代码上:

verifySignatureOnServer() verifySignatureOnServer()

  private boolean verifySignatureOnServer(String data, String signature) {
        String retFromServer = "";
        URL url;
        HttpsURLConnection urlConnection = null;
        try {
            String urlStr = "https://www.example.com/verify.php?data=" + URLEncoder.encode(data, "UTF-8") + "&signature=" + URLEncoder.encode(signature, "UTF-8");

            url = new URL(urlStr);
            urlConnection = (HttpsURLConnection) url.openConnection();
            InputStream in = urlConnection.getInputStream();
            InputStreamReader inRead = new InputStreamReader(in);
            retFromServer = convertStreamToString(inRead);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }

        return retFromServer.equals("good");
    }

convertStreamToString() convertStreamToString()

 private static String convertStreamToString(java.io.InputStreamReader is) {
        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";
    }

verify.php on the root directory of web hosting虚拟主机根目录下的verify.php

<?php
// get data param
$data = $_GET['data'];

// get signature param
$signature = $_GET['signature'];

// get key
$key_64 = ".... put here the base64 encoded pub key from google play console , all in one row !! ....";



$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 "good";
} elseif ($ok == 0) {
    echo "bad";
} else {
    die ("fault, error checking signature");
}

// free the key from memory
openssl_free_key($key);

?>

NOTES:注意事项:

  • You should encrypt the URL in your java code, if not the URL can be found easy with a simple text search in your decompressed app apk您应该在您的 java 代码中加密 URL,如果没有,可以通过在解压缩的应用程序 apk 中进行简单的文本搜索来轻松找到该 URL

  • Also better to change php file name, url arguments, good/bad reponses to something with no sense.也最好将 php 文件名、url 参数、好/坏响应更改为毫无意义的东西。

  • verifySignatureOnServer() should be run in a separated thread if not a network on main thread exception will be thrown.如果不会抛出主线程上的网络异常,则 verifySignatureOnServer() 应在单独的线程中运行。 An alternative would be to use Volley.另一种方法是使用 Volley。

IN-APP BILLING LIBRARY UPDATE应用内计费库更新

Using the library, the data to be verified is returned by Purchase.getOriginalJson() and the signature by Purchase.getSignature()使用库,需要验证的数据由Purchase.getOriginalJson()返回,签名由Purchase.getSignature()

Hope it will help ...希望它会有所帮助...

  1. Add entry in database when user make in-app purchase.当用户进行应用内购买时在数据库中添加条目。
  2. When user open your app check whether purchase is valid or invalid.当用户打开您的应用程序时,检查购买是否有效。
  3. If valid then proceed to next activity otherwise show error message.如果有效,则继续下一个活动,否则显示错误消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM