Skip to content

Fix: Change OKP JWK thumbprint to use crv/kty/x, not RSA's kty/n/x - #26

Open
nomadium wants to merge 1 commit into
jwt:mainfrom
nomadium:fix-okp-jwk-thumbprint
Open

Fix: Change OKP JWK thumbprint to use crv/kty/x, not RSA's kty/n/x#26
nomadium wants to merge 1 commit into
jwt:mainfrom
nomadium:fix-okp-jwk-thumbprint

Conversation

@nomadium

Copy link
Copy Markdown

Description

Fix OKP JWK thumbprint: use crv/kty/x, not RSA's kty/n/x

OKP_PUBLIC_KEY_ELEMENTS was copy-pasted from an RSA-shaped element list (kty, n, x). "n" is the RSA modulus and never applies to OKP (Ed25519) keys, so it always serialized as null; "crv" is required by RFC 8037 but was missing entirely.

This list feeds JWK::OKP#members, which JWT::JWK::Thumbprint (RFC 7638) uses directly to compute the SHA-256 thumbprint, and jwt's default kid_generator (:key_digest) uses that thumbprint as the auto-generated "kid" for every key this gem creates. As a result, every kid produced by this gem is computed over the wrong JSON ({"kty":"OKP","n":null,"x":"..."}) instead of the RFC 7638-correct {"crv":"Ed25519","kty":"OKP","x":"..."}, so it never matches the thumbprint a spec-compliant verifier computes for the same key.

Add a regression test pinned to the published RFC 8037 Appendix A.3 thumbprint test vector.

Checklist

Before the PR can be merged be sure the following are checked:

  • There are tests for the fix or feature added/changed

Notes

I stumbled upon this issue after investigating why JWK keys generated by Linzer gem (which depends on jwt-eddsa) and associated HTTP message signatures were failing verification at a CloudFlare debug utility website.

OKP_PUBLIC_KEY_ELEMENTS was copy-pasted from an RSA-shaped element
list (kty, n, x). "n" is the RSA modulus and never applies to OKP
(Ed25519) keys, so it always serialized as null; "crv" is required by
RFC 8037 but was missing entirely.

This list feeds JWK::OKP#members, which JWT::JWK::Thumbprint (RFC
7638) uses directly to compute the SHA-256 thumbprint, and jwt's
default kid_generator (:key_digest) uses that thumbprint as the
auto-generated "kid" for every key this gem creates. As a result,
every kid produced by this gem is computed over the wrong JSON
({"kty":"OKP","n":null,"x":"..."}) instead of the RFC 7638-correct
{"crv":"Ed25519","kty":"OKP","x":"..."}, so it never matches the
thumbprint a spec-compliant verifier computes for the same key.

Add a regression test pinned to the published RFC 8037 Appendix A.3
thumbprint test vector.
nomadium added a commit to nomadium/linzer that referenced this pull request Aug 10, 2026
…sa's kid

jwt-eddsa (<= 0.9.0) computes JWK::OKP's thumbprint over the wrong
members ({kty, n, x} instead of the RFC 8037-correct {crv, kty, x}),
so the Web Bot Auth `keyid` derived from it never matched what a
spec-compliant verifier expects.

Add Linzer::JWS::Key#jwk_thumbprint and use it instead, so Linzer
is correct independent of jwt/ruby-jwt-eddsa#26.
@anakinj anakinj changed the title Fix OKP JWK thumbprint: use crv/kty/x, not RSA's kty/n/x Fix: Change OKP JWK thumbprint to use crv/kty/x, not RSA's kty/n/x Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant