I'm using Keycloak 4.8.0 as authentication server. I have configured a realm that issues JWT that are signed with EC512. I'm obtaining the token via the endpoint https://example.com/auth/realms/myrealm/protocol/openid-connect/token
by providing client ID, client secret, username and password of a user.
When introspecting the JWT with Keycloak via https://example.com/auth/realms/myrealm/protocol/openid-connect/token/introspect
it is shown as valid. I then have a Node.js application build on top of LoopBack 4 which provides a REST service. There I want to verify the obtained JWT with passport-jwt
. I provided the public key, but I always get the error TypeError: "ES512" signatures must be "132" bytes, saw "138"
. (Interestingly, when using Keycloak 4.7.0 the error was TypeError: "ES512" signatures must be "132" bytes, saw "139"
).
So the signature seems to be invalid. E.g. https://jwt.io is able to decode the JWT but also does not show a valid signature when provided with the public key. It may be possible that the public key is invalid. In addition of copying the key from the admin console I have used https://example.com/auth/realms/myrealm/protocol/openid-connect/certs
to retrieve the key. I then converted it to PEM with the help of this answer. The keys matched.
So I'm a bit at a loss here. Of course, it could be possible that Keycloak generates invalid signatures, but I doubt it. It is more likely that I do something wrong, maybe at the realm configuration, but I don't see where.
For anyone wanting to try to verify the signature here is a example JWT which I have obtained as described above:
eyJhbGciOiJFUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJwdEVYeWpnbGlwdlp3OGRXSUc1Ml8xNFpONTdnWHNtWUdrdUVJSEplSVJrIn0.eyJqdGkiOiJiNmI1NTI4Ni0zY2NiLTRiNzQtYWFlZC1hOGI2MzBiZjQ5NmEiLCJleHAiOjE1NDUwODM0NjYsIm5iZiI6MCwiaWF0IjoxNTQ1MDgzMTY2LCJpc3MiOiJodHRwczovL2F1dGguaW5tYXQubG9jL2F1dGgvcmVhbG1zL2lubWF0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjViNWQ5NmI1LTBmZjgtNDAyYi05NDAxLTQyYTExODAzMjFlZiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImlubWF0IiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiZjAxMmIzOTMtYTY0Ny00ZDhkLTk4MDQtZDQ3MzNkM2Y4MjVjIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdGVyIiwiZW1haWwiOiJ0ZXN0ZXJAdGVzdC5jb20ifQ.MIGIAkIBzvH1R-9fNFp8jlw-TeFidmC03uNov6IhDc23XMB9eHga8zdF4ybDmxDoAkB-NAJnDRUDNCtw3ooRxNSApje9oCkCQgHkrbYSN3L5LBA1OM5yb9WSQVaxItcspnCtMtW1QogaAYp0v9JwQA7VHL6ofEp3pcXLaKnFzVgP6FvDCwGgIJGFfw
And here is the public key which I got by copying it from the admin console:
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBTrJ+u+k3rqKmuvzykwcMfJMVEieQtc1ldlj2Q9vfsWHbNc95xmnsIgcYcsJNVZCY8NnzFBmYSa0G7rNjclS8xGQB4uDs4KV91WaDRmc3DqwDvupvWVw3M1RG64FteoGwq098p6bxog/tgyNWeYzOTpfunXi0Yp4p+ZrMxlaYdSMuDyU=
Since passport-jwt
wants it in PEM format I input it to the library as follows:
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBTrJ+u+k3rqKmuvzykwcMfJMVEieQ
tc1ldlj2Q9vfsWHbNc95xmnsIgcYcsJNVZCY8NnzFBmYSa0G7rNjclS8xGQB4uDs
4KV91WaDRmc3DqwDvupvWVw3M1RG64FteoGwq098p6bxog/tgyNWeYzOTpfunXi0
Yp4p+ZrMxlaYdSMuDyU=
-----END PUBLIC KEY-----
Update: When using RS256 I get the signature to verify. So it might indeed be a Keycloak bug.