Why does the token change when private key is entered in verify signature?

,

Hi. I’m new to JWT and have been generating them with command line after receiving a key pair from a company whose api I need to integrate with. Their requirements for their token signature are specified as RSASHA256(
base64UrlEncode(header) + “.” +
base64UrlEncode(body),
“<your_public_RSA_key>”,
“<your_private_RSA_key>”
). Their docs say they only want the JWT signed with the private key, as seems typical, so my last command line is SIGNATURE=$(openssl dgst -sha256 -sign <(echo -n “${PrivateKey}”) <(echo -n “${HEADER_PAYLOAD}”) | openssl base64 -A | tr -d ‘=’ | tr ‘/+’ ‘_-’ | tr -d ‘\n’ )
(I know -A seems redundant with tr -d ‘=’ but without the tr -d ‘=’ it was including forbidden extra padding in the form of =.) So I generate my token, and paste it in to the debugger to verify it worked, and when I paste in my public key, it says “Signature verified”. The token doesn’t change. I wouldn’t expect it to. Why would it? I go on my merry way, but the api is not happy with this token. After watching their YouTube for the Nth time, I notice they’re pasting the private key into the verifier as well, and then I notice the similarity in requested format on the debugger page, and when I do this, it changes the key. I thought my JWT was what I had originally pasted in, but apparently not, but it’s not just changing the signature part. It’s changing the whole key, so it seems it’s not just “verifying” - it’s adding another level of building to add the public and private key, base64 encoded - header, body, and signature separately, and then re-encrypting, and thus resigning the whole thing with RSASHA256 - is that what’s happening? That new value is the value they want. It seems like a token within a token, and the “verifier” is not just verifying, it’s creating an outer shell and actually building onto the existing token. Can anyone validate this? If that’s what’s happening, I find the label “verify signature” in this context misleading, especially since it can be “verified” with just the public key - without the private key - without changing the original token. Please note that this is not a JWT generated for Okta authentication. I appreciate Okta for hosting this forum. Thanks in advance for any clarification that can be provided.

Hey there @vivaladata welcome to the community!

Thanks for the detailed description - Not sure how much I can help, but the behavior you’re describing is odd indeed :thinking: The JWT should only be signed using the private key, not verified.

jwt.io is be able to verify an RS256 jwt by just pasting it into the “Encoded” field - No other action is required:

It’s hard to know what could be going on with the API you are attempting to pass the JWT to, but to my knowledge all validation libraries work this same way.

Thank you. I’ve been able to successfully generate a JWT that the api will accept. It’s just strange the way I have to generate it - using the jwt.io validator to alter the code while it validates; however, in generating it, I can set it to expire a long time out, so while I’m developing, I’ll store the JTW and keep using it to generate new shorter access tokens. That works for development purposes, and hopefully I can get it worked out when I circle back around to it.

No problem, happy to help where I can! Very interesting, you’ll have to keep us posted moving forward. Glad things are working for dev purposes for the time being :slight_smile:

I tried it again and this time your system accepted the original JWT without the alteration. Maybe I had a paragraph break or some other rogue hidden character included when I tried the submission before. https://jwt.io does still change the token contents when you include the private key for verification, though. I wonder if it’s re-encoding it with a new time.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.