Closed advdv closed 5 months ago
You are ENCRYPTING and then SIGNING. jwt.ParseXXXX
only does signature verification/unwrapping. You need to use jwe.Decrypt
yourself to decrypt your token before calling jwt.ParseXXX
(or jws.Verify
)
Ah, ok. Thank you for the super fast reply. I did try that (see below) but I got the error compact JWE format must have five parts (3)
so I figured I should leave it to a higher level abstraction to do it. I wil do more research and learn about what "compact" means.
decrypted, err := jwe.Decrypt([]byte(cookie.Value),
jwe.WithKeySet(e.keys.encrypt.public))
if err != nil {
return "", fmt.Errorf("failed to decrypt session cookie: %w", err)
}
An, sorry, in your case you need to jws.Verify
, then jwe.Decrypt
, and then finally jwt.Parse
.
That is, you are doing signed = Sign(Encrypt(JWT_payload))
, so in order to get back the JWT_payload
, you need to do ParseJWT(Decrypt(Verify(signed)))
I highly suggest you look into how these messages are constructed from the RFCs or similar.
I'm now doing the following:
verified, err := jws.Verify([]byte(cookie.Value), jws.WithKeySet(e.keys.signing.public))
if err != nil {
return "", fmt.Errorf("failed to verify session token: %w", err)
}
decrypted, err := jwe.Decrypt(verified, jwe.WithKeySet(e.keys.encrypt.private))
if err != nil {
return "", fmt.Errorf("failed to decrypt session token: %w", err)
}
fmt.Println(string(decrypted)) // {"rt":"some.refresh.token"}
parsed, err := jwt.Parse(decrypted,
jwt.WithClock(e.clock),
jwt.WithKeySet(e.keys.signing.public))
if err != nil {
return "", fmt.Errorf("failed to parse session token: %w", err)
}
But it will fail on the final parse because "decrypted" now just looks like this: {"rt":"some.refresh.token"}
. I will look into how this exactly works but I just want to report it here in case it's unexpected. The error is : failed to unmarshal jws message: required field "signatures" not present
Ofcourse, I now have the data I was looking for so it is fine. Just reporting here in case it's unexpected
The last error is because you're trying to jwt.Parse
with the key set -- that is, you're verifying the message signature. If the payload you end up with is a JSON message, you could either simply use json.Unmarshal
, or use jwt.Parse
with the jwt.WithVerify(false)
option. I'm not claiming I have the best documentation, but these are all documented, so please take a bit of time looking at the documentation or the examples
directory.
I will, thank you again for the quick responses (and the great library). I will close this, maybe others in the future have use for the information in this thread.
no prob. Thanks for the kind words
Thank you for this great library! I'm trying to store a refresh token in an encrypted JWT. Thinking I don't want to implement such critical security functionality from scratch I figured I used the high-level jwt.NewSerializer. It seems to allow for signing and encrypting a payload. But I don't understand how I'm supposed to parse it. I always seem to get
"unsupported format (#2)"
I great the token like this
The keys come from two key sets. One for encryption, one of signing (as I understand that we require different key for this). I then go ahead an try to parse it like this:
The
e.keys
, looks like this:This is an example token:
eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.ZXlKaGJHY2lPaUpTVTBFdFQwRkZVQ0lzSW1WdVl5STZJa0V5TlRaSFEwMGlMQ0owZVhBaU9pSktWMVFpZlEubFVCR1NhcmFJOG9Sd29vRTBKblhnb3BFNndyS3gzZWxVUWdYczdSQ1RtUlpIR0NSVi1hdlpDdjQzUmltbUJ6RC1pa1JSWDJXNnVEcGVnbV9ZbVlxU3JKV2h2RW92SlRoSWpfQXJDaXN1OGR0M1NHRWJvR1RrWmU4TUE1VkN4RTFxNWthQTJ0bHhzeU5xWDN6MGcyd0daWXZSZ3JHSDJQZk5PVkxiQ2RxX0hmZmE5TER4U2pKNlRiZ0ZWZi1FSjJyMkdTS09HbHFFU2xPRGtoalp1b25RMXRkaWZvcDlDRXdsclp3S0ZPOUdRclBITkQxMkQwNmJvaVhnemhWWGUxTldsRklya3VLZ2xndXNoWGI1aDBHLWUzNnh4WWZEZUpOMTBJNXFtSTg1Y0tKV05vaHREWEtWa2JTaV94dnIwMWJCTGMzWHVSQmNabVJFSDdKQjdTYllBLklOUEY0YmlHbFlTTkpSdUkuWnNIQVVaeEtzb0tGTV84OUFVTDY2YU1GX21sUGFwYUNUSjEtLkdqNXNpRElRUWZvZ2YzR2pIY1JLOXc.w6o725mvW4bnZJ1XlzvnqAIQxIg13imuJwE6pLR1uyc
The testing keys I'm using look like this (well-known, just used for testing):
And