【问题标题】:PHP : verify JWS with JWK (x5c)PHP:使用 JWK (x5c) 验证 JWS
【发布时间】:2021-12-09 00:28:43
【问题描述】:

上下文:我想用 Payconiq 实现支付。付款完成后,Payconiq 会调用我的 API 为我提供付款信息(状态等)。

我正在使用 Symfony 和 web-token/jwt-bundle 来验证 JWS。

1/ 我使用 'base64_decode' 从令牌中获取标头(令牌格式类似于:header.payload.signature 带有空负载)

2/ 我从 URL 获取 json JWK:似乎总是使用的 JWK 如下:

{
      "kty": "EC",
      "use": "sig",
      "x5t#S256": "******************",
      "crv": "P-256",
      "kid": "kid.2021",
      "alg": "ES256",
      "x5c": [],
      "x": *******,
      "y": *******

3/ 我想用这个 JWK 验证签名。我愿意:

$serializerManager = new JWSSerializerManager([new CompactSerializer(),]);

$jws = $serializerManager->unserialize($token);

$isVerified = $jwsVerifier->verifyWithKey($jws, $jwk, 0, $payload);

(公共函数 verifyWithKey(JWS $jws, JWK $jwk, int $signature, ?string $detachedPayload = null): bool)

我的payload:Payconiq发送的body请求(支付信息)。

$isVerified 总是假的。

我不知道问题是来自我的有效负载还是我使用库的方式(文档显示了一个带有 JWK 之类的示例

{
    "kty": "oct",
    "k": "dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g'
}

有一个“k”键,结果没问题(isVerified = true)。

但是对于没有“k”和“x5c”的 JWK,isVerified 仍然为 false。

有人可以帮帮我吗?

【问题讨论】:

    标签: php jwt symfony5 jwk


    【解决方案1】:

    验证失败,因为您忘记在$jwsVerifier 对象中设置适当的签名算法(ES256)。

    在下文中找到一个有效的例子。请使用您的数据更改 JWK 和令牌值。

    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!');
    }
    

    如果负载与令牌分离,您可以将其设置为verifyWithKey 方法的第四个参数。 请注意,它不应是 base 64 编码的。

    <?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!');
    }
    

    【讨论】:

    • 感谢您的回答,我在$jmsVerifier(framework.yaml)中有几个算法,包括ES256。我认为问题来自我可能没有正确使用的有效载荷或 JWK,我不知道。我收到的令牌不包含有效负载,我不确定我应该如何重建它(或者即使我应该真正重建它)。我很清楚这有点模糊:/
    • 您好,为了有效,您的ES256 密钥应至少具有kty: "EC"、crv: "P-256"、x 和y 属性。我编辑了我的答案,向您展示如何管理分离的有效负载(无需重建任何东西)
    • 感谢您的帮助!问题是:有效载荷中不必要的空格。
    猜你喜欢
    • 2021-06-25
    • 2019-10-21
    • 2021-05-09
    • 2020-08-01
    • 2020-07-25
    • 2019-08-09
    • 2021-12-17
    • 2022-12-24
    • 2022-10-31
    相关资源
    最近更新 更多