3

我正在使用以下函数(服务器端 php)来验证 IAB v3 事务:

我从 android 应用程序传递:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

                         String signed_data=data.getStringExtra(IabHelper.RESPONSE_INAPP_PURCHASE_DATA);
                         String signature=data.getStringExtra(IabHelper.RESPONSE_INAPP_SIGNATURE);

我有一种感觉,这可能与我正在传递的签名有关。我正在使用以下 Android 方法对其进行编码,因为没有编码我得到一个错误:

public String URLsafe(String text){
        try {
            return URLEncoder.encode(text, "utf-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();;
        }
        return null;
    }

我正在传递网址

http://www.example.com/handlepayment.php?signature=....&data=....


public String getXmlFromUrl(String url) {

        String xml = null;

        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new   MyHttpClient_ALKS(myContext.getApplicationContext());
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);

            HttpEntity httpEntity = httpResponse.getEntity();
            xml = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
         return xml;
    }

到服务器:

function verify_play($signed_data, $signature) 
{
  global $public_key_base64;
  $pkey =  "-----BEGIN PUBLIC KEY-----\n".
    chunk_split($public_key_base64, 64,"\n").
    '-----END PUBLIC KEY-----';   
  //using PHP to create an RSA key
  $pkey = openssl_get_publickey($pkey);
  //$signature should be in binary format, but it comes as BASE64. 
  //So, I'll convert it.
  $signature = base64_decode($signature);   
  //using PHP's native support to verify the signature
  $result = openssl_verify(
      $signed_data,
      $signature,
      $pkey,
      OPENSSL_ALGO_SHA1);

  if (0 === $result) 
  {
    return false;
  }
  else if (1 !== $result)
  {
    return false;
  }
  else 
  {
    return true;
  }
} ;

它似乎总是返回 false ($result=0),有人知道为什么吗?如何传递未编码的签名,或者我应该使用哪种编码?

4

1 回答 1

1

根据我的经验openssl_get_publickey(),只有当您在 X.509 证书中有公钥时才会创建公钥资源。

我的建议是使用phpseclib,一个纯 PHP RSA 实现。例如。

function verify_play($signed_data, $signature) 
{
  global $public_key_base64;
  $rsa = new Crypt_RSA();
  $rsa->loadKey($public_key_base64);
  $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
  $signature = base64_decode($signature);   
  return $rsa->verify($signed_data, $signature);
}
于 2013-12-04T07:55:28.330 回答