Skip to content

Support for DPoP #9712

Closed
Closed

Description

@geniqtech

Does this library support DPoP (Demonstration of Proof-of-Procession)?
If so, any sample code?

Activity

  1. bshaffer commented on Nov 21, 2023

    @bshaffer
    Contributor

    I don't know much about DPoP, but looking at the RFC, it seems like JWTs are used in DPoP, not the other way around. So this library should be able to help you implement DPoP, but there may not be a specific DPoP support added here.

  2. added
    type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.
    on Nov 21, 2023
  3. rbro commented on Jan 9, 2025

    @rbro

    I believe DPoP requires you to create your own JWK. Is creating a JWK something that could be added to php-jwt?

  4. bshaffer commented on Jan 9, 2025

    @bshaffer
    Contributor

    You can create a JWT using this library. That and validating JWTs are this library's main function.

    See JWT::encode

    https://github.com/firebase/php-jwt/blob/29fa2ce9e0582cd397711eec1e80c05ce20fabca/src/JWT.php#L199

  5. rbro commented on Jan 9, 2025

    @rbro

    I believe DPoP requires you to create your own JWK, not JWT. At least from looking at this tutorial - https://developer.okta.com/docs/guides/dpop/nonoktaresourceserver/main

  6. bshaffer commented on Feb 11, 2025

    @bshaffer
    Contributor

    @rbro

    I think generating a JWK is definitely within the scope of this library, but I am not sure that I know what that particular method would look like or why it would be useful. It would take some designing.

  7. bshaffer commented on Oct 30, 2026

    @bshaffer
    Contributor

    Closing this out as DPoP (RFC 9449) can already be implemented using JWT::encode(), JWK::parseKey(), and JWT::decode().

    To create and verify a DPoP proof JWT today (e.g. with ES256), extract the public key coordinates from OpenSSL to build the jwk header:

    use Firebase\JWT\JWK;
    use Firebase\JWT\JWT;
    
    $privateKey = openssl_pkey_new([
        'private_key_type' => OPENSSL_KEYTYPE_EC,
        'curve_name' => 'prime256v1',
    ]);
    
    $details = openssl_pkey_get_details($privateKey);
    $jwk = [
        'kty' => 'EC',
        'crv' => 'P-256',
        'x' => JWT::urlsafeB64Encode(str_pad($details['ec']['x'], 32, "\x00", STR_PAD_LEFT)),
        'y' => JWT::urlsafeB64Encode(str_pad($details['ec']['y'], 32, "\x00", STR_PAD_LEFT)),
    ];
    
    // Sign the DPoP proof JWT
    $dpopProof = JWT::encode([
        'jti' => bin2hex(random_bytes(16)),
        'htm' => 'POST',
        'htu' => 'https://server.example.com/token',
        'iat' => time(),
    ], $privateKey, 'ES256', null, [
        'typ' => 'dpop+jwt',
        'jwk' => $jwk,
    ]);
    
    // Verify the DPoP proof JWT using the public JWK
    $decoded = JWT::decode($dpopProof, JWK::parseKey($jwk, 'ES256'));

    I also opened draft PR #9835 to explore adding a JWK::createFromKey() helper for exporting keys to JWK arrays directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions