I need to verify a signature in an api endpoint, but whatever I tried I can't validate it. Data comes from mobile device.
Key pair is created on android through this library and in particular, with these functions.
composer.json
{
"require": {
"phpseclib/phpseclib": "^3.0",
"kint-php/kint": "^4.2"
}
}
index.php
<?php
require "vendor/autoload.php";
use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\RSA\PublicKey;
use phpseclib3\Crypt\RSA;
$message = "CIAO";
$signature = "nu92wNMUDDUgZJbrKOIJt09FOfvMvQ6fWlNCfvkxqhUuGIT7hCnikQCM4KfXJN/X7D3+ISQvu1+BbVYug2uvxDwtDt7mHRr7lo7SRN6/yFq237LJ9iHZNZWXz1Ict1ez92Aa1oeDZtMpO84VOrVE372UNOETFvz+AaeTJ3lO/3WV+xu+uQ36FiOhLtAi7CXFhCki3+P6oO0Va1PtB2rmdiMcbHSkn3y5IZG5UTxLtRYr0dkTbbq+ySNMdYY01Yd1aOHl7phgoR+sRHQwOaq2/IHAahBOTZShrjLy5b/DmDaYwjjAs76FSQFiWtPjtm0WdiroGbzdwsHjWgBXKyHzHA==";
$hash = hash('sha256', $message, true);
$publicKey = "
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4sNG1i5Tiqc2nz5nFU8
Q7UaKbOqV2jTCB0Alg2hwT6GQX/GhPTHiPicoLPX1yubPbDxn9e/4ZPCwdfW20JG
4oaGNUnT6VSfH9Tx5ckBGIYzsHbRU7llKgMFK91RVrTCb/3v1sSEHBthby2C4c2V
N1zDCZxaTGfY3zgsEhUIYHhagam1c/WHR9mVCu+9a9QwsMgJ9ppKwikzLyetNkla
MvIKzTxsFHrtZrmBhlbmRHFXGKqqwvnwxkER14YpldiXBFUJ1/p4JHE09byfxmC/
9kRjFxqOxU3hwvO2YlRbk9/T8+6mtyyUxHLLK37vBYOuvKEaPIKM/ASm8UiZLwqq
swIDAQAB
-----END RSA PUBLIC KEY-----
";
$key = PublicKeyLoader::loadPublicKey($publicKey, $password = false);
\Kint::dump(
$publicKey,
$key::getSupportedKeyFormats(),
$key->getLoadedFormat(),
$key->getPadding(),
(string) $key->getHash(),
$key,
$key instanceof \phpseclib3\Crypt\Common\PublicKey,
$key->verify(base64_decode($message, true), base64_decode($signature, true)),
$key->verify(base64_decode($message, true), $signature),
$key->verify($message, base64_decode($signature, true)),
$key->verify($message, $signature),
$key->verify($hash, base64_decode($signature, true))
);
Result:
I verified signature with success with this tool online here
Obviously there is something that I miss, but I can't figured out
Validates fine for me with this code:
$message = "CIAO";
$signature = "nu92wNMUDDUgZJbrKOIJt09FOfvMvQ6fWlNCfvkxqhUuGIT7hCnikQCM4KfXJN/X7D3+ISQvu1+BbVYug2uvxDwtDt7mHRr7lo7SRN6/yFq237LJ9iHZNZWXz1Ict1ez92Aa1oeDZtMpO84VOrVE372UNOETFvz+AaeTJ3lO/3WV+xu+uQ36FiOhLtAi7CXFhCki3+P6oO0Va1PtB2rmdiMcbHSkn3y5IZG5UTxLtRYr0dkTbbq+ySNMdYY01Yd1aOHl7phgoR+sRHQwOaq2/IHAahBOTZShrjLy5b/DmDaYwjjAs76FSQFiWtPjtm0WdiroGbzdwsHjWgBXKyHzHA==";
$publicKey = "-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4sNG1i5Tiqc2nz5nFU8
Q7UaKbOqV2jTCB0Alg2hwT6GQX/GhPTHiPicoLPX1yubPbDxn9e/4ZPCwdfW20JG
4oaGNUnT6VSfH9Tx5ckBGIYzsHbRU7llKgMFK91RVrTCb/3v1sSEHBthby2C4c2V
N1zDCZxaTGfY3zgsEhUIYHhagam1c/WHR9mVCu+9a9QwsMgJ9ppKwikzLyetNkla
MvIKzTxsFHrtZrmBhlbmRHFXGKqqwvnwxkER14YpldiXBFUJ1/p4JHE09byfxmC/
9kRjFxqOxU3hwvO2YlRbk9/T8+6mtyyUxHLLK37vBYOuvKEaPIKM/ASm8UiZLwqq
swIDAQAB
-----END RSA PUBLIC KEY-----";
$signature = base64_decode($signature);
$key = PublicKeyLoader::load($publicKey)->withPadding(RSA::SIGNATURE_PKCS1);
echo $key->verify($message, $signature) ? 'good' : 'bad';
The key thing I'm doing that you're not is ->withPadding(RSA::SIGNATURE_PKCS1)
. sha256
is the default hash for phpseclib v3 so you don't need to do anything with that. Also, my code cleans up some redundancies in your code.