Reputation: 11
Context: I want to implement payment with Payconiq. When the payment is done, Payconiq calls my API to give me payment information (status, etc).
I'm using Symfony and web-token/jwt-bundle to verify JWS.
1/ I use 'base64_decode' to get the header from the token (token format is like: header.payload.signature with an empty payload)
2/ I get the json JWKs from URL: the JWK that always seems to be used is like:
{
"kty": "EC",
"use": "sig",
"x5t#S256": "******************",
"crv": "P-256",
"kid": "kid.2021",
"alg": "ES256",
"x5c": [],
"x": *******,
"y": *******
3/ I want to verify the signature with this JWK. I do :
$serializerManager = new JWSSerializerManager([new CompactSerializer(),]);
$jws = $serializerManager->unserialize($token);
$isVerified = $jwsVerifier->verifyWithKey($jws, $jwk, 0, $payload);
(public function verifyWithKey(JWS $jws, JWK $jwk, int $signature, ?string $detachedPayload = null): bool)
My payload: body request sent by Payconiq (payment information).
$isVerified is always false.
I don't know if the problem comes from my payload or the way I use the library (documentation shows an example with a JWK like
{
"kty": "oct",
"k": "dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g'
}
There's is a "k" key and the result is ok (isVerified = true).
But with a JWK without "k" and with "x5c", isVerified still false.
Could someone please help me?
Upvotes: 0
Views: 1609
Reputation: 16695
It looks like the verification failed because you have have forgotten to set the appropriate signature algorithm (ES256
) in the $jwsVerifier
object.
Find hereafter a valid example. Please change the JWK and token values with you data.
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\ES256;
use Jose\Component\Signature\Serializer\CompactSerializer;
use Jose\Component\Signature\JWSVerifier;
$jwk = JWK::createFromJson('{"kty":"EC","crv":"P-256","x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU","y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"}');
$token = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q';
$serializerManager = new CompactSerializer();
$jws = $serializerManager->unserialize($token);
$algorithmManager = new AlgorithmManager([new ES256()]);
$jwsVerifier = new JWSVerifier($algorithmManager);
$isVerified = $jwsVerifier->verifyWithKey($jws, $jwk, 0);
if ($isVerified) {
var_dump('Signature is valid');
} else {
var_dump('Signature is NOT valid!');
}
In case the payload is detached from the token, you can set it as fourth parameter of the verifyWithKey
method.
Note that it shall not be base 64 encoded.
<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\ES256;
use Jose\Component\Signature\Serializer\CompactSerializer;
use Jose\Component\Signature\JWSVerifier;
$jwk = JWK::createFromJson('{"kty":"EC","crv":"P-256","x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU","y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"}');
$token = 'eyJhbGciOiJFUzI1NiJ9..DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q';
$payload = base64_decode('eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ');
$serializerManager = new CompactSerializer();
$jws = $serializerManager->unserialize($token);
$algorithmManager = new AlgorithmManager([new ES256()]);
$jwsVerifier = new JWSVerifier($algorithmManager);
$isVerified = $jwsVerifier->verifyWithKey($jws, $jwk, 0, $payload);
if ($isVerified) {
var_dump('Signature is valid');
} else {
var_dump('Signature is NOT valid!');
}
Upvotes: 1