问题
I'm using the following function (server side php) to verify a IAB v3 transaction:
I'm passing from the android app:
@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);
I have a feeling it may have something to do with the signature I'm passing. I'm using the following Android method to encode it, because without encoding I get an error:
public String URLsafe(String text){
try {
return URLEncoder.encode(text, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();;
}
return null;
}
I'm passing the url
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;
}
to the server:
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;
}
} ;
It always seem to return false ($result=0), anybody any idea why? How can I pass the signature un-encoded, or which encoding should I use?
回答1:
In my experience openssl_get_publickey()
only creates public key resources when you have a public key in an X.509 cert.
My recommendation would be to use phpseclib, a pure PHP RSA implementation. eg.
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);
}
来源:https://stackoverflow.com/questions/20261977/php-server-side-iab-verification-openssl-verify-always-returns-0