Closed Obnotname closed 4 years ago
Hi Obnotname,
There a few issues with the usage of the library in your code, here is the corrected example:
` $publicKeyPem = "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+nzvoGqvDeB9+SzE6igTl7TyK4JB\nbglwir9oTcQta8NuG26ZpZFxt+F2NDk7asTE6/2Yc8i1ATcGIqtuS5hv0Q==\n-----END PUBLIC KEY-----"; $signatureBase64 = "MEQCIB5DcAc4SO-gjbEFu-ZYfG_LGkX-tp4Nb0DIMjh71SQeAiBAwXcveOUVDcmQ4Royc1Fxbzd13n7gc3AN4QXbPsdvSw"; $message = "some_message";
$publicKey = EllipticCurve\PublicKey::fromPem($publicKeyPem); $signature = EllipticCurve\Signature::fromBase64($signatureBase64); echo "\n" . EllipticCurve\Ecdsa::verify($message, $signature, $publicKey); `
Hope you find it useful!
No problem! And sorry about the huge delay on our reply. In case you're interested, we actually implemented the same ECDSA interface in several languages, including Python.
Ah no problem :) Great to know that 👍
Hi, it's me again.
I have now tried your example, however it still returns false on verification
That's because either the public key or the signature do not match the provided message. Here is an example that returns true on verification:
`<?php require_once "vendor/autoload.php";
$message = "some_message";
$privateKey = new EllipticCurve\PrivateKey(); $publicKeyPem = $privateKey->publicKey()->toPem(); $signatureBase64 = EllipticCurve\Ecdsa::sign($message, $privateKey)->toBase64(); echo "public key: " . $publicKeyPem; echo "signature: " . $signatureBase64;
$publicKey = EllipticCurve\PublicKey::fromPem($publicKeyPem); $signature = EllipticCurve\Signature::fromBase64($signatureBase64); if (EllipticCurve\Ecdsa::verify($message, $signature, $publicKey)) { echo "\nMessage is valid\n"; } else { echo "\nMessage is invalid\n"; }`
I am not familiar with the lib you're using. The same example would look like this using our python lib:
from ellipticcurve.publicKey import PublicKey
from ellipticcurve.ecdsa import Ecdsa
from ellipticcurve.signature import Signature
import base64
import urllib
publicKey = """
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGpRlChCiilDu5el58I5Vp6YEmyuvVgzq
Z6VzxPayVUj95fgucEt2SZMVSCO5NE5ngErDC7W/BGROltpc4sMe6w==
-----END PUBLIC KEY-----"""
signature = "MEYCIQDGj4F6TW79PT3lA6dHSNdya-OgVZuyHoWt2n4ZlFGvawIhAOftl2zIq7Ki2HQujVOzWAsia_uO4ojCtLJM4ZGvpk94"
message = "ad_network=5450213213286189855&ad_unit=3430014594&reward_amount=7&reward_item=Reward×tamp=1593684944978&transaction_id=0cb3fbbe45d94d991763e98fe3668d44&user_id=erik.boscher%40web.de"
prepared_msg = urllib.parse.unquote(message)
prepared_key = PublicKey.fromPem(publicKey)
prepared_sig = Signature.fromDer(base64.urlsafe_b64decode(signature + "==="))
result = Ecdsa.verify(
message=prepared_msg,
signature=prepared_sig,
publicKey=prepared_key,
)
print(result)
Which, as you noted, prints False.
My only guess is that the code is not correctly rebuilding the prepared_msg with the current parsing. If any message bytes are out of place during verification, the signature and public key won't verify it. If possible, try to understand exactly how the message was encoded for transmission, as the process has to be precisely reversed for this verification to work.
The signature is base64 encoded websafe! You must convert the signature before.
// credits to https://www.php.net/manual/de/function.base64-encode.php#103849
function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
After that you can use it like this
$signature = \EllipticCurve\Signature::fromDer(base64url_decode("MEYCIQCQfAX-JkarkUSduywcSAm00wN0UfhUmXQvaZSci4chVgIhAMbl6ZXX_dKl5BWYhLLWzlsUrgr_ptpxEJvHsZJCLL2e"));
[Closed]