Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: RFC7638 JWK Thumbprint calculation #1032

Open
DavidBuchanan314 opened this issue Jan 19, 2025 · 1 comment
Open

Feature Request: RFC7638 JWK Thumbprint calculation #1032

DavidBuchanan314 opened this issue Jan 19, 2025 · 1 comment

Comments

@DavidBuchanan314
Copy link

DavidBuchanan314 commented Jan 19, 2025

As specified in https://www.rfc-editor.org/rfc/rfc7638.html

This is useful for implementing DPoP, part of OAuth 2.0

@DavidBuchanan314
Copy link
Author

DavidBuchanan314 commented Jan 20, 2025

A lightly tested implementation:

import json
import hashlib
import base64
import jwt

# in lexicographic order as described in rfc7638
JWK_REQUIRED_MEMBERS = {
	"EC": ("crv", "kty", "x", "y"),
	"RSA": ("e", "kty", "n"),
	"oct": ("k", "kty"),
}

def jwk_thumbprint(jwk: jwt.PyJWK) -> str:
	jwk_dict = jwk.Algorithm.to_jwk(jwk.key, as_dict=True)
	members = JWK_REQUIRED_MEMBERS.get(jwk.key_type)
	if members is None:
		raise jwt.exceptions.PyJWKError(
			f"I don't know how to canonicalize key type {jwk.key_type}"
		)
	json_bytes = json.dumps(
		{k: jwk_dict[k] for k in members},
		separators=(",", ":"),
	).encode()
	json_hash = hashlib.sha256(json_bytes).digest()
	return base64.urlsafe_b64encode(json_hash).rstrip(b"=").decode()


if __name__ == "__main__":
	# rfc7638 test vector
	test_key = jwt.PyJWK.from_dict({
		"kty": "RSA",
		"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
		"e": "AQAB",
		"alg": "RS256",
		"kid": "2011-04-29"
	})
	print(jwk_thumbprint(test_key))

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

No branches or pull requests

1 participant