Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在我的服务器上验证Android应用内计费交易?_Php_Android_In App Billing - Fatal编程技术网

Php 如何在我的服务器上验证Android应用内计费交易?

Php 如何在我的服务器上验证Android应用内计费交易?,php,android,in-app-billing,Php,Android,In App Billing,我制作了一个Android应用程序,可以使用它购买物品。当一件物品被购买时,交易可以很容易地在Android Market和手机之间同步,以便在应用程序中使用。但是,我需要我的服务器知道购买。交付特定于应用程序的数据的决定应该在我的服务器上做出,而不是在客户端应用程序中 例如 用户从Android Market购买物品X 事务数据Y被发送到客户端 客户端将Y发送到我的服务器 客户端要求服务器为X交付内容 如果Y有效,服务器将交付内容。如何做到这一点 Q:我如何验证来自Android客户端(可能来

我制作了一个Android应用程序,可以使用它购买物品。当一件物品被购买时,交易可以很容易地在Android Market和手机之间同步,以便在应用程序中使用。但是,我需要我的服务器知道购买。交付特定于应用程序的数据的决定应该在我的服务器上做出,而不是在客户端应用程序中

例如

  • 用户从Android Market购买物品X
  • 事务数据Y被发送到客户端
  • 客户端将Y发送到我的服务器
  • 客户端要求服务器为X交付内容
  • 如果Y有效,服务器将交付内容。如何做到这一点
  • Q:我如何验证来自Android客户端(可能来自谷歌服务器)的交易数据是否是假的?也就是说,黑客没有生成数据

    谷歌服务器->安卓客户端->我的服务器->安卓客户端

    也许这更像是一个PHP问题。为了验证检索到的数据是真实的,我的服务器脚本(PHP)应该做什么

    在Eclipse中将其作为项目安装,并让您的项目将其作为库导入

    我们实现了BillingController.i配置,类似于

    import net.robotmedia.billing.BillingController;
    
    public class PhoneBillingConfiguration implements BillingController.IConfiguration{
        @Override
        public byte[] getObfuscationSalt() {
            return new byte[] {1,-2,3,4,-5,6,-7,theseshouldallberandombyteshere,8,-9,0};
        }
    
        @Override
        public String getPublicKey() {
            return "superlongstringhereIforgothowwemadethis";
        }
    }
    
    然后,对于我们的应用程序,我们扩展了
    应用程序

    public class LocalizedApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    
    //      BillingController.setDebug(true);
            BillingController.setConfiguration(new PhoneBillingConfiguration());
        }
    }
    
    AndroidManifest包括这个(以及所有其他内容)

    这是上面最后几行调用您的类的代码,它将实际与您的服务器进行通信

    我们的PhoneServerLink从以下内容开始:

    public class PhoneServerLink implements GetJSONListener {
    
        public PhoneServerLink(Context context) {
            mContext = context;
        }
    
        public boolean validateSignature(String signedData, String signature) {
            return getPurchaseResultFromServer(signedData, signature, false);
        }
    
        private boolean getPurchaseResultFromServer(String signedData, String signature,  boolean async) {  
                // send request to server using whatever protocols you like 
        }
    
    }
    

    事务数据使用特定于应用程序的私钥签名。还有一个nonce可以防止重播(即多次发送相同、有效的数据)。如果您验证nonce是唯一的,并且签名在您的服务器上是有效的,那么您可以合理地确定它不是伪造的。查看有关IAB的部分进行讨论。

    使用openssl\u验证($data、$signature、$key)

    变量$data和$signature应该使用https从android客户端发送到php服务器。事务包含这两个项目。在确认客户端上的事务之前,将其发送到服务器。(请参阅此处的文档-)

    变量$key是您的google公钥,可从许可和应用内计费面板的发布者帐户获得。复制公钥并在php代码中使用,最好使用安装在服务器上的配置文件,而不是实际的php代码


    如果openssl_verify调用成功,您应该将订单号存储在服务器上,并确保它们是唯一的,以便无法重播。请注意,一个数据收据和签名对可能包含多个订单号,尽管它通常是一个订单。

    Hm.听起来是正确的方法。但是如何检查签名是否有效?我正在使用PHP。使用PHP的OpenSSl函数。您可以从开发控制台获取公钥。准确的代码可以在上面找到,所以,甚至有一个项目在谷歌代码上做这个,IIRC。将检查IIRC,但我怀疑公钥在这里会有帮助。它存储在客户端应用程序中,因此攻击者可以提取它并使用它生成虚假交易。您需要再次读取文档。私钥在谷歌服务器中。它签署交易。除非有人破解这些,否则他们不可能生成“虚假交易”。公钥通常存储在客户端应用程序中,仅用于验证。如果你有一个验证服务器,它不必在应用程序中,它会留在服务器上。研究我链接的幻灯片了解更多细节。不难找到:。它看起来不是很活跃,但你应该明白。代码看起来不错,但我相信这更像是服务器端的问题。我的服务器代码如何确定请求(事务信息)是否有效;除了你的问题,我什么都回答了!嗯,也许这对有相反问题的人来说是件好事固定的。(非常令人惊讶的是,github在更改它时没有考虑到这一点!)@ThunderRabbit我想为应用内购买编写一个代码,其中我想提供在我的应用内购买视频的工具,视频存储在我自己的服务器中。那么你有关于这个和“Android计费库”的教程吗在我们的项目中使用安全??这是一个非常大的文档。我有问题。什么是$data?什么是$签名?我们如何知道我们收到了来自谷歌服务器的请求?我们将响应发送回哪里?openssl\u verify是对其openssl库的PHP函数调用-。在检查谷歌服务器方面-我认为谷歌不支持相互身份验证(),否则当你连接到谷歌服务器时,你只需检查类似于浏览器的SSL证书。@Agamenus-注意,你不需要呼叫谷歌服务器-你只需要使用SSL呼叫你的服务器。你确实需要从谷歌的服务器上获取公钥,但是你可以在Band外获取,我很困惑。例如,如果我要使用Paypal的系统对购买进行身份验证,Paypal会向我的服务器发送一条消息,对交易进行身份验证。如果是GooglePlay应用内购买,而我的服务器向用户发送了一些信息,我的服务器如何知道有人购买,以及是谁购买的?等待你是说Google发送了一个$signature字符串来解码$data,我可以使用他们的公钥(在哪里?)来解码和验证?谷歌的例子开始有意义了,但它看起来仍然很抽象。@Agamenus-谷歌将签名和数据发送到手机/设备。手机会将此有效负载发送到服务器。您正在验证此有效负载实际上是由google发送的-由google签名。您仍然需要检查负载是否没有被重放,负载可能有多个订单。以下是在我的项目中运行良好的简单代码:
    public class PhoneSignatureValidator implements ISignatureValidator {
        private final String TAG = this.getClass().getSimpleName();
        private PhoneServerLink mServerLink;
    
    
        private BillingController.IConfiguration configuration;
    
        public PhoneSignatureValidator(Context context, BillingController.IConfiguration configuration, String our_product_sku) {
            this.configuration = configuration;
            mServerLink = new PhoneServerLink(context);
            mServerLink.setSku(our_product_sku);
        }
    
    
        @Override
        public boolean validate(String signedData, String signature) {
            final String publicKey;
            if (configuration == null || TextUtils.isEmpty(publicKey = configuration.getPublicKey())) {
                Log.w(BillingController.LOG_TAG, "Please set the public key or turn on debug mode");
                return false;
            }
            if (signedData == null) {
                Log.e(BillingController.LOG_TAG, "Data is null");
                return false;
            }
            // mServerLink will talk to your server
            boolean bool = mServerLink.validateSignature(signedData, signature);
            return bool;
        }
    
    }
    
    public class PhoneServerLink implements GetJSONListener {
    
        public PhoneServerLink(Context context) {
            mContext = context;
        }
    
        public boolean validateSignature(String signedData, String signature) {
            return getPurchaseResultFromServer(signedData, signature, false);
        }
    
        private boolean getPurchaseResultFromServer(String signedData, String signature,  boolean async) {  
                // send request to server using whatever protocols you like 
        }
    
    }