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

jwt.verify() always evaluates as false for Google-issued JWT when using certificate verification #46

Closed
johnswarbrick opened this issue Nov 12, 2023 · 5 comments

Comments

@johnswarbrick
Copy link

johnswarbrick commented Nov 12, 2023

Hi -

Using @tsndr/[email protected] I always get false when trying to verify a Google-issued JWT with a certificate.

This is basically the same issue as #28 logged by @Zombobot1

I'm using JWTs and certificates issued by Google firebase. The certificates are provided here:

https://www.googleapis.com/robot/v1/metadata/x509/[email protected]

I'm extracting the kid from the JWT and using that to match with the specific certificate that should be used to validate the JWT.

I tried using the raw certificate as supplied by Google, tried removing the -----BEGIN CERTIFICATE----- prefix/suffix and tried removing line feeds but it always verifies as false.

Rather than supplying my own JWT/certificate I've re-used those from the previously raised ticket.

Would really appreciate some help with this one!

async function test() {
  const token = `eyJhbGciOiJSUzI1NiIsImtpZCI6ImE5NmFkY2U5OTk5YmJmNWNkMzBmMjlmNDljZDM3ZjRjNWU2NDI3NDAiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiQWxpIE9tYXJvdiIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQUZkWnVjcVdlUWd0RnE1cVZBcDJyOC1pbU8yeVhmVXUySWhBZktGWU5PZVA9czk2LWMiLCJpbml0ViI6MSwicm9sZSI6ImFkbWluIiwiYWNjb3VudCI6ImFkbWluIiwiaXNzIjoiaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGUuY29tL3VuaXZlcnNlLTU1Y2VjIiwiYXVkIjoidW5pdmVyc2UtNTVjZWMiLCJhdXRoX3RpbWUiOjE2NjgwNDM3MTIsInVzZXJfaWQiOiJZWkZQN25RT28xUnNFakJqSjRzZHlzdWFQU28yIiwic3ViIjoiWVpGUDduUU9vMVJzRWpCako0c2R5c3VhUFNvMiIsImlhdCI6MTY2OTc0MDE4NywiZXhwIjoxNjY5NzQzNzg3LCJlbWFpbCI6ImFsaWsub21hcm92MzAwMEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJnb29nbGUuY29tIjpbIjEwNzY5NjU3NjE2NTExNjE5MDgzNyJdLCJlbWFpbCI6WyJhbGlrLm9tYXJvdjMwMDBAZ21haWwuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoiZ29vZ2xlLmNvbSJ9fQ.TJ6XeEcR3dtG-bVRDKrA4FXPN-v_U2c_HGRMWLc57Qg5lMt8sNYEhKWmFkrcoslSHPhKDRqQOD5JQlrVIgNzJoQY7pm4vSGpoTnz6pRfAtC64TrtanQaUChW8lI2StdKDNXe_j_b3F7mlZj9xFLNxjpnBim3LaF-mxLMqtC6IdQ9xENvJEsDDwOHS77VjNtY2ZhlXwnTWVq7UTbThOQETQdlYBBCLPgqMYSACzTfLli-wgfe3pIEAUXeygBxWqAgYnSDAm-Z47X1yAzQUyVlbITAfCUZZXiGonHs4YoNMWVqWDkWgNsIspKWRWUcSzgVjZFS7HChyYI_uIP0FejgsA`
  const key = `-----BEGIN CERTIFICATE-----
MIIDHTCCAgWgAwIBAgIJAJsmCdlCEtdXMA0GCSqGSIb3DQEBBQUAMDExLzAtBgNV
BAMMJnNlY3VyZXRva2VuLnN5c3RlbS5nc2VydmljZWFjY291bnQuY29tMB4XDTIy
MTExOTA5MzkwOFoXDTIyMTIwNTIxNTQwOFowMTEvMC0GA1UEAwwmc2VjdXJldG9r
ZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDPx5SngqCrMJVQ/lFC9kP7Mgnhs4aIIbaquM42Z/zG1c80
EPEhTlRz9Cltc6wtj0wmRPi9x8HtIRlyoo4ps6LCXH0GxJZ6hZHGlcGUbFTAbVsY
aUWqteiXb2umTEnFV8+IaeOqVvSnJ97RIRcMSa7McKL+AkdjKPuDvdK5R6SHnnML
3HNJ8Xla1YOWmYkgCAgUNGLLg5bl8M6zyicNg8ZPGV7ndIzjrXuy9yKorpljNzZJ
hymT29yIq3hFInk+GGaSEaRIW6Zz0QjxUSgjDS75yxHnNM9Sgik3I6X8SHKO6mdY
aG4GAQUcuHr8eaZH9vYR0RG50c+fMw/P38nr0i8VAgMBAAGjODA2MAwGA1UdEwEB
/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMCMA0G
CSqGSIb3DQEBBQUAA4IBAQCvRsaUOJj8yA5Ul/LhoBFwEmZaQuU5sUKWGMJJj4ug
WzBPtCEfsmYsMQWmaSY7PiHn7eOF7rUL6FRaHvy1sMwF+xp4xomrIp+GQPQA4hra
AlgJRUUslTMJkbypsZ6PMWMLJw2WtyFcaIq/5vdywExwcfi+Gi7lDHTyfSCTiDvq
qK85W7OpqkmSxFKcva9Gi0tLLNgrRR9953Pwqis3LRVwKX6yXQ0j0v2pTmIyH/zp
VrUK77PjKaWlZISsmLH5dF4Olclx6hRFhvUYVXmT0K/hqr4pBZWukt4D9cD6ZSem
qFbFBUPmxj4clHXqiqRmQ3tv6MkpudXzCNb0wYWk+3TU
-----END CERTIFICATE-----`
  console.log(await jwt.verify(token, key, { algorithm: 'RS256' }))
}
@johnswarbrick
Copy link
Author

johnswarbrick commented Nov 12, 2023

Update - the error seems to be:

NotSupportedError: Unrecognized key import format \"spki\"."

I've tried lots of other JWT validation libraries, but none of them run on Cloudflare Workers due to missing crypto library dependencies. Hoping there is a solution with cloudflare-worker-jwt

@tsndr
Copy link
Owner

tsndr commented Nov 12, 2023

Hey @johnswarbrick,

thanks for bringing this to my attention and providing data to test with, really appreciated.

Will take a look and let you know once I've implemented a fix :)

@tsndr
Copy link
Owner

tsndr commented Nov 12, 2023

Hey @johnswarbrick,

The WebCrypto API doesn't currently support importing X.509 keys, supporting this would require a bit more work, and since I want to keep this library lightweight, I don't really want to ship all of that code just to support this scenario. I hope you can understand :)

If you're looking for a heavier, but more feature-full implementation of JWT, check out panva/jose

@tsndr tsndr closed this as completed Nov 12, 2023
@tsndr tsndr closed this as not planned Won't fix, can't repro, duplicate, stale Nov 12, 2023
@johnswarbrick
Copy link
Author

Thanks @tsndr, that's a shame as I like your very lightweight library, but I completely understand your decision! Really appreciate you looking into this so quickly.

@tsndr
Copy link
Owner

tsndr commented Nov 12, 2023

If you really want to keep using this library you could Parse the X509 certificate on your end and just pass the resulting public key to jwt.verify().

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

2 participants