-1

I need to verify a signature, which is a security feature in google's developer android api. They have a working example, which is written in kotlin.

Atm. I am trying to convert this code:

val decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT)
val keyFactory = KeyFactory.getInstance("RSA")
return keyFactory.generatePublic(X509EncodedKeySpec(decodedKey))

The encodedPublicKey is fix. I get it from google.

I installed phpseclib and currently I try to convert the above code:

$decodedKey = base64_decode($encodedPublicKey);
$x509 = new X509();
$x509->loadX509($encodedPublicKey);
$rsa = $x509->getPublicKey();
return [$rsa, $x509];

I discovered that not even base64_decode($encodedPublicKey) works. It returns nothing, while the kotlin code Base64.decode(encodedPublicKey, Base64.DEFAULT) returns many decoded keys, example:

D/IABUtil/Security: decodedKey 0 :48

EDIT

kotlins Base64.decode(encodedPublicKey, Base64.DEFAULT) returns a bytearray. I managed to get the same result by using unpack() in php:

$decodedKey = unpack('c*', $decodedKey); // ByteArray
Roman
  • 3,563
  • 5
  • 48
  • 104
  • Can you post `$encodedPublicKey`? Seeing what format it's in might give me some insight into how to best load it with phpseclib. In lieu of that I wonder if this would work better: `$rsa = new RSA; $rsa->loadKey($encodedPublicKey);`. The thing is... X509EncodedKeySpec doesn't necessarily imply that the key is being used in an X.509 cert. phpseclib calls this this PKCS8. – neubert Jan 17 '20 at 18:42
  • @neubert I solved it already, but forgot to answer, will do on monday. I used open_ssl_verify for this and solved it in 4 lines. Very simple. – Roman Jan 17 '20 at 20:58

1 Answers1

0

So at the end I used open ssl for this.

$publicKey = env('BASE_64_ENCODED_PUBLIC_KEY');

$key = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($publicKey, 64, "\n") . "-----END PUBLIC KEY-----";
$key = openssl_get_publickey($key);
if (false === $key) {
    return ["Could not get public Key"];
}

$verify = openssl_verify($originalJson, base64_decode($signature), $key, "sha1WithRSAEncryption");

Credit: android in app billing v3 with php

It was important to convert the public key into the correct format. It must have 64 characters in each line.

Roman
  • 3,563
  • 5
  • 48
  • 104
  • Your Java / Kotlin code didn't do any signature verification so it's hard to say that that's a direct conversion. Your phpseclib code didn't do any signature verification either but given how you're doing the verification with your OpenSSL code I can already tell what the issue you probably had with phpseclib was: phpseclib, by default, uses the more secure (but less common) OAEP padding whereas OpenSSL uses, by default, the more common (but less secure) PKCS1 padding. – neubert Jan 24 '20 at 05:05
  • To get phpseclib to give matching results you'd need to do `$rsa->setSignatureMode(RSA::::SIGNATURE_PKCS1)` and `$rsa->setHash('sha1')` prior to `$rsa->verify()`. – neubert Jan 24 '20 at 05:05
  • @neubert Thank you for adding this information. Might help some people in future. – Roman Jan 24 '20 at 07:33