Should I be able to see patterns in a HS256 encoded JWT?Would encrypting a signed JWT prove viable to secure claims payload?Is this authentication scheme using JWT secure?jwt in message payload?Storing JWT in SPAJWT: Why is audience important?JWT: In a server-to-server request, should I sign the entire request body?
Travelling to Paris by train during strike in December 2019
Did the computer mouse always output relative x/y and not absolute?
"Don't invest now because the market is high"
Should I still follow "programming to an interface not implementation" even if I think using concrete class members is the simpler solution?
Prospective employer asking for my current pay slip during interview
What's the best way to keep cover of a pan slightly opened?
Typing "PartOf" in excel changes automatically to part of?
How do electric hot water heaters explode and what can be done to prevent that from happening?
What should be done if I suspect a player is using weighted dice?
Is Jupiter still an anomaly?
Intersection of sorted lists
What should I do about a new employee who didn't mention their second job or planned leave?
Density plot on the surface of a sphere
Template not provided using create-react-app
A novel (or maybe a whole series) where a weird disease infects men and machines
Why so few osilloscope with dedicated isolated channels?
How to replace all elements of a list by a rule "element" -> "element_"
Retracting Recommendation Letters
How do professors and lecturers learn to teach?
Do all 7th progessions sound good as triad progressions?
Is it possible to stall a plane so bad that the nose refuses to go down due to no airspeed?
What movie or fandom is this jewelry from?
If I buy a super off-peak ticket, can I travel on a off-peak train and pay the difference?
Do Adventure cards count towards "number of instant and sorcery cards in your graveyard"?
Should I be able to see patterns in a HS256 encoded JWT?
Would encrypting a signed JWT prove viable to secure claims payload?Is this authentication scheme using JWT secure?jwt in message payload?Storing JWT in SPAJWT: Why is audience important?JWT: In a server-to-server request, should I sign the entire request body?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
I was fiddling with https://jwt.io/ using this header
"alg": "HS256",
"typ": "JWT"
when I realized that replacing the payload name with something repetitive like AAAAAAAAAAAAAAAAAAAA
would produce a token such as this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBIiwiaWF0IjoxNTE2MjM5MDIyfQ.hlXlWvaeyOb6OcrOwd-xfWgF8QlfmTycj5WWZwRr6FY
You can see that the BQUF
substring appears to be repeated. The more A
s I added to the name, the more BQUF
s show up.
As far as I know the presence of these kind of patterns makes it considerably easier to find out the encoded contents. What am I missing?
encryption jwt token
add a comment
|
I was fiddling with https://jwt.io/ using this header
"alg": "HS256",
"typ": "JWT"
when I realized that replacing the payload name with something repetitive like AAAAAAAAAAAAAAAAAAAA
would produce a token such as this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBIiwiaWF0IjoxNTE2MjM5MDIyfQ.hlXlWvaeyOb6OcrOwd-xfWgF8QlfmTycj5WWZwRr6FY
You can see that the BQUF
substring appears to be repeated. The more A
s I added to the name, the more BQUF
s show up.
As far as I know the presence of these kind of patterns makes it considerably easier to find out the encoded contents. What am I missing?
encryption jwt token
5
Just for completeness, JWT can use encryption as defined by JWE, however in your case (alg=HS256
) it is a JWS (signature) instead.
– eckes
Sep 28 at 15:32
@eckes is correct. tools.ietf.org/html/rfc7518#section-5.1
– Adam Williams
Sep 29 at 16:33
3
@Bob has a more complete answer than mine. I think you should accept his instead.
– Conor Mancone
Sep 29 at 23:38
add a comment
|
I was fiddling with https://jwt.io/ using this header
"alg": "HS256",
"typ": "JWT"
when I realized that replacing the payload name with something repetitive like AAAAAAAAAAAAAAAAAAAA
would produce a token such as this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBIiwiaWF0IjoxNTE2MjM5MDIyfQ.hlXlWvaeyOb6OcrOwd-xfWgF8QlfmTycj5WWZwRr6FY
You can see that the BQUF
substring appears to be repeated. The more A
s I added to the name, the more BQUF
s show up.
As far as I know the presence of these kind of patterns makes it considerably easier to find out the encoded contents. What am I missing?
encryption jwt token
I was fiddling with https://jwt.io/ using this header
"alg": "HS256",
"typ": "JWT"
when I realized that replacing the payload name with something repetitive like AAAAAAAAAAAAAAAAAAAA
would produce a token such as this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBIiwiaWF0IjoxNTE2MjM5MDIyfQ.hlXlWvaeyOb6OcrOwd-xfWgF8QlfmTycj5WWZwRr6FY
You can see that the BQUF
substring appears to be repeated. The more A
s I added to the name, the more BQUF
s show up.
As far as I know the presence of these kind of patterns makes it considerably easier to find out the encoded contents. What am I missing?
encryption jwt token
encryption jwt token
asked Sep 27 at 18:17
jmacedojmacedo
4292 silver badges6 bronze badges
4292 silver badges6 bronze badges
5
Just for completeness, JWT can use encryption as defined by JWE, however in your case (alg=HS256
) it is a JWS (signature) instead.
– eckes
Sep 28 at 15:32
@eckes is correct. tools.ietf.org/html/rfc7518#section-5.1
– Adam Williams
Sep 29 at 16:33
3
@Bob has a more complete answer than mine. I think you should accept his instead.
– Conor Mancone
Sep 29 at 23:38
add a comment
|
5
Just for completeness, JWT can use encryption as defined by JWE, however in your case (alg=HS256
) it is a JWS (signature) instead.
– eckes
Sep 28 at 15:32
@eckes is correct. tools.ietf.org/html/rfc7518#section-5.1
– Adam Williams
Sep 29 at 16:33
3
@Bob has a more complete answer than mine. I think you should accept his instead.
– Conor Mancone
Sep 29 at 23:38
5
5
Just for completeness, JWT can use encryption as defined by JWE, however in your case (
alg=HS256
) it is a JWS (signature) instead.– eckes
Sep 28 at 15:32
Just for completeness, JWT can use encryption as defined by JWE, however in your case (
alg=HS256
) it is a JWS (signature) instead.– eckes
Sep 28 at 15:32
@eckes is correct. tools.ietf.org/html/rfc7518#section-5.1
– Adam Williams
Sep 29 at 16:33
@eckes is correct. tools.ietf.org/html/rfc7518#section-5.1
– Adam Williams
Sep 29 at 16:33
3
3
@Bob has a more complete answer than mine. I think you should accept his instead.
– Conor Mancone
Sep 29 at 23:38
@Bob has a more complete answer than mine. I think you should accept his instead.
– Conor Mancone
Sep 29 at 23:38
add a comment
|
3 Answers
3
active
oldest
votes
There's a bit of confusion of terminology here.
JWT defines the basic format of the claims, and some standard claims. It specifies that the JWT Claims Set should either be the payload of a JWS or a JWE structure.
JWS defines a structure for some payload with a signature. While the payload is almost always JWT in practice, this is not a requirement of the specification. The most common form is the JWS Compact Serialization, which is the Base64'd Header.Payload.Signature
you are familiar with. Note there is no encryption involved, only signing. This can1 guarantee that the token was created by a trusted party and not modified (authenticity), but will not hide its contents.
JWE is the encrypted counterpart to JWS. Much like JWS, it most often contains a JWT payload (as its plaintext) but this is not a requirement. JWE Compact Serialization is somewhat different from the JWS equivalent: Header.Key.IV.Ciphertext.AuthenticationTag
. This should1 have the same security guarantees (authenticity)2 as JWS, with the addition of hiding the message from anyone without the key (confidentiality).
What you have there is specifically a JWS, which is signed but not encrypted (as seen in the HS256
algorithm, which stands for "HMAC using SHA-256"). If you need encryption, you should instead create a JWE with one of the encryption algorithms defined by JWA.
Further reading:
- Understanding ID Token
- JWT, JWS and JWE for Not So Dummies! (Part I)
- RFC 7519 JSON Web Token (JWT)
- RFC 7515 JSON Web Signature (JWS)
- RFC 7516 JSON Web Encryption (JWE)
1 As always, any "guarantees" depend on everything being configured correctly. And that you're not e.g. using a debugging config that leaves everything unencrypted/unsigned.
2 Assuming authenticated encryption.
This. Thanks for properly explaining the (confusing) terminology around JWT, JWS, and JWE.
– sleske
Sep 30 at 8:13
Indeed. Taking the section with repeated characters over to base64decode.org produces: "sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
– Steve Sether
Oct 3 at 15:04
add a comment
|
tl/dr: Your selected version of the JWT doesn't encrypt anything, it merely encodes it for easy
transport. The data in the payload is not meant to be a secret.
You have a JWS (JWT with signature). What you are looking at is simply the base64 encoded data payload. A JWS contains 3 parts:
- The base64 encoded header
- The base64 encoded data
- A cryptographic signature
Base64 is simply an encoding format - not any kind of encryption, and is not meant to hide the data. Rather, it just makes sure it is composed solely of standard ASCII characters that easily survive transfer between different systems. As a result, if you were to take everything in between the two periods and run it through a base64 decoder, you would see your original payload data without issue.
The key therefore is simple: a JWS isn't meant to hide the data. It is simply intended (through the signature) to ensure data integrity, i.e. if someone changes the data payload then you will know because your signature will no longer match.
Alternately you could use a JWE (JWT with encryption) to hide your data. See Bob's excellent answer for a more detailed comparison between JWT, JWS, and JWE, all of which are closely related.
Of course. Thanks. I had this misconception in my mind that the jwt could only be read by those having the secret, but it turns out that it's just a vehicle for information which we need to make sure came from a legitimate source.
– jmacedo
Sep 27 at 19:16
@jmacedo Yup, that's exactly correct. It's easy to get confused about because base64 data certainly looks encrypted, which is even more true when you realize that a lot of encrypted data is actually displayed in a base64 encoding.
– Conor Mancone
Sep 27 at 19:19
7
It's also certainly possible to put encrypted data into the JWT data, but then it's not the JWT hiding it.
– Bobson
Sep 29 at 0:06
7
This answer assumes that all JWT are (unencrypted) JWS. It may be useful to mention JWE (which are a valid representation of JWT, and are supported by many of the same libraries). (@Bobson - if one uses JWE, then it is the JWT/JWE spec that defines the encryption hiding it.)
– Bob
Sep 29 at 17:09
4
Sorry, but I have to -1 because encrypted JWTs (using the JWE format) are quite common in the applications I work with. This would be a stronger answer if you mentioned that the OP is seeing that behaviour because their JWTs are signed (with an HMAC signature), but in general a JWT can be signed, or encrypted, or both, or neither.
– Mike Ounsworth
Sep 29 at 21:26
|
show 1 more comment
What you're missing is that your token is signed (or, more precisely, authenticated with a symmetric key) but not encrypted.
If you take the token in your question above, split it into three pieces at the periods (.
) and feed each piece into a base64 decoder, you'll get the following decoded outputs:
"alg":"HS256","typ":"JWT"
"sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
and a sequence of 32 mostly non-ASCII bytes which is the 256-bit HMAC authentication tag for the rest of the token. As you can see, all the data is there easily readable by anyone. The authentication tag only prevents anyone who doesn't know the secret HMAC key from modifying the token or creating forged tokens from scratch.
add a comment
|
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "162"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f218801%2fshould-i-be-able-to-see-patterns-in-a-hs256-encoded-jwt%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
There's a bit of confusion of terminology here.
JWT defines the basic format of the claims, and some standard claims. It specifies that the JWT Claims Set should either be the payload of a JWS or a JWE structure.
JWS defines a structure for some payload with a signature. While the payload is almost always JWT in practice, this is not a requirement of the specification. The most common form is the JWS Compact Serialization, which is the Base64'd Header.Payload.Signature
you are familiar with. Note there is no encryption involved, only signing. This can1 guarantee that the token was created by a trusted party and not modified (authenticity), but will not hide its contents.
JWE is the encrypted counterpart to JWS. Much like JWS, it most often contains a JWT payload (as its plaintext) but this is not a requirement. JWE Compact Serialization is somewhat different from the JWS equivalent: Header.Key.IV.Ciphertext.AuthenticationTag
. This should1 have the same security guarantees (authenticity)2 as JWS, with the addition of hiding the message from anyone without the key (confidentiality).
What you have there is specifically a JWS, which is signed but not encrypted (as seen in the HS256
algorithm, which stands for "HMAC using SHA-256"). If you need encryption, you should instead create a JWE with one of the encryption algorithms defined by JWA.
Further reading:
- Understanding ID Token
- JWT, JWS and JWE for Not So Dummies! (Part I)
- RFC 7519 JSON Web Token (JWT)
- RFC 7515 JSON Web Signature (JWS)
- RFC 7516 JSON Web Encryption (JWE)
1 As always, any "guarantees" depend on everything being configured correctly. And that you're not e.g. using a debugging config that leaves everything unencrypted/unsigned.
2 Assuming authenticated encryption.
This. Thanks for properly explaining the (confusing) terminology around JWT, JWS, and JWE.
– sleske
Sep 30 at 8:13
Indeed. Taking the section with repeated characters over to base64decode.org produces: "sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
– Steve Sether
Oct 3 at 15:04
add a comment
|
There's a bit of confusion of terminology here.
JWT defines the basic format of the claims, and some standard claims. It specifies that the JWT Claims Set should either be the payload of a JWS or a JWE structure.
JWS defines a structure for some payload with a signature. While the payload is almost always JWT in practice, this is not a requirement of the specification. The most common form is the JWS Compact Serialization, which is the Base64'd Header.Payload.Signature
you are familiar with. Note there is no encryption involved, only signing. This can1 guarantee that the token was created by a trusted party and not modified (authenticity), but will not hide its contents.
JWE is the encrypted counterpart to JWS. Much like JWS, it most often contains a JWT payload (as its plaintext) but this is not a requirement. JWE Compact Serialization is somewhat different from the JWS equivalent: Header.Key.IV.Ciphertext.AuthenticationTag
. This should1 have the same security guarantees (authenticity)2 as JWS, with the addition of hiding the message from anyone without the key (confidentiality).
What you have there is specifically a JWS, which is signed but not encrypted (as seen in the HS256
algorithm, which stands for "HMAC using SHA-256"). If you need encryption, you should instead create a JWE with one of the encryption algorithms defined by JWA.
Further reading:
- Understanding ID Token
- JWT, JWS and JWE for Not So Dummies! (Part I)
- RFC 7519 JSON Web Token (JWT)
- RFC 7515 JSON Web Signature (JWS)
- RFC 7516 JSON Web Encryption (JWE)
1 As always, any "guarantees" depend on everything being configured correctly. And that you're not e.g. using a debugging config that leaves everything unencrypted/unsigned.
2 Assuming authenticated encryption.
This. Thanks for properly explaining the (confusing) terminology around JWT, JWS, and JWE.
– sleske
Sep 30 at 8:13
Indeed. Taking the section with repeated characters over to base64decode.org produces: "sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
– Steve Sether
Oct 3 at 15:04
add a comment
|
There's a bit of confusion of terminology here.
JWT defines the basic format of the claims, and some standard claims. It specifies that the JWT Claims Set should either be the payload of a JWS or a JWE structure.
JWS defines a structure for some payload with a signature. While the payload is almost always JWT in practice, this is not a requirement of the specification. The most common form is the JWS Compact Serialization, which is the Base64'd Header.Payload.Signature
you are familiar with. Note there is no encryption involved, only signing. This can1 guarantee that the token was created by a trusted party and not modified (authenticity), but will not hide its contents.
JWE is the encrypted counterpart to JWS. Much like JWS, it most often contains a JWT payload (as its plaintext) but this is not a requirement. JWE Compact Serialization is somewhat different from the JWS equivalent: Header.Key.IV.Ciphertext.AuthenticationTag
. This should1 have the same security guarantees (authenticity)2 as JWS, with the addition of hiding the message from anyone without the key (confidentiality).
What you have there is specifically a JWS, which is signed but not encrypted (as seen in the HS256
algorithm, which stands for "HMAC using SHA-256"). If you need encryption, you should instead create a JWE with one of the encryption algorithms defined by JWA.
Further reading:
- Understanding ID Token
- JWT, JWS and JWE for Not So Dummies! (Part I)
- RFC 7519 JSON Web Token (JWT)
- RFC 7515 JSON Web Signature (JWS)
- RFC 7516 JSON Web Encryption (JWE)
1 As always, any "guarantees" depend on everything being configured correctly. And that you're not e.g. using a debugging config that leaves everything unencrypted/unsigned.
2 Assuming authenticated encryption.
There's a bit of confusion of terminology here.
JWT defines the basic format of the claims, and some standard claims. It specifies that the JWT Claims Set should either be the payload of a JWS or a JWE structure.
JWS defines a structure for some payload with a signature. While the payload is almost always JWT in practice, this is not a requirement of the specification. The most common form is the JWS Compact Serialization, which is the Base64'd Header.Payload.Signature
you are familiar with. Note there is no encryption involved, only signing. This can1 guarantee that the token was created by a trusted party and not modified (authenticity), but will not hide its contents.
JWE is the encrypted counterpart to JWS. Much like JWS, it most often contains a JWT payload (as its plaintext) but this is not a requirement. JWE Compact Serialization is somewhat different from the JWS equivalent: Header.Key.IV.Ciphertext.AuthenticationTag
. This should1 have the same security guarantees (authenticity)2 as JWS, with the addition of hiding the message from anyone without the key (confidentiality).
What you have there is specifically a JWS, which is signed but not encrypted (as seen in the HS256
algorithm, which stands for "HMAC using SHA-256"). If you need encryption, you should instead create a JWE with one of the encryption algorithms defined by JWA.
Further reading:
- Understanding ID Token
- JWT, JWS and JWE for Not So Dummies! (Part I)
- RFC 7519 JSON Web Token (JWT)
- RFC 7515 JSON Web Signature (JWS)
- RFC 7516 JSON Web Encryption (JWE)
1 As always, any "guarantees" depend on everything being configured correctly. And that you're not e.g. using a debugging config that leaves everything unencrypted/unsigned.
2 Assuming authenticated encryption.
edited Oct 3 at 3:04
answered Sep 29 at 17:08
BobBob
1,01310 silver badges12 bronze badges
1,01310 silver badges12 bronze badges
This. Thanks for properly explaining the (confusing) terminology around JWT, JWS, and JWE.
– sleske
Sep 30 at 8:13
Indeed. Taking the section with repeated characters over to base64decode.org produces: "sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
– Steve Sether
Oct 3 at 15:04
add a comment
|
This. Thanks for properly explaining the (confusing) terminology around JWT, JWS, and JWE.
– sleske
Sep 30 at 8:13
Indeed. Taking the section with repeated characters over to base64decode.org produces: "sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
– Steve Sether
Oct 3 at 15:04
This. Thanks for properly explaining the (confusing) terminology around JWT, JWS, and JWE.
– sleske
Sep 30 at 8:13
This. Thanks for properly explaining the (confusing) terminology around JWT, JWS, and JWE.
– sleske
Sep 30 at 8:13
Indeed. Taking the section with repeated characters over to base64decode.org produces: "sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
– Steve Sether
Oct 3 at 15:04
Indeed. Taking the section with repeated characters over to base64decode.org produces: "sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
– Steve Sether
Oct 3 at 15:04
add a comment
|
tl/dr: Your selected version of the JWT doesn't encrypt anything, it merely encodes it for easy
transport. The data in the payload is not meant to be a secret.
You have a JWS (JWT with signature). What you are looking at is simply the base64 encoded data payload. A JWS contains 3 parts:
- The base64 encoded header
- The base64 encoded data
- A cryptographic signature
Base64 is simply an encoding format - not any kind of encryption, and is not meant to hide the data. Rather, it just makes sure it is composed solely of standard ASCII characters that easily survive transfer between different systems. As a result, if you were to take everything in between the two periods and run it through a base64 decoder, you would see your original payload data without issue.
The key therefore is simple: a JWS isn't meant to hide the data. It is simply intended (through the signature) to ensure data integrity, i.e. if someone changes the data payload then you will know because your signature will no longer match.
Alternately you could use a JWE (JWT with encryption) to hide your data. See Bob's excellent answer for a more detailed comparison between JWT, JWS, and JWE, all of which are closely related.
Of course. Thanks. I had this misconception in my mind that the jwt could only be read by those having the secret, but it turns out that it's just a vehicle for information which we need to make sure came from a legitimate source.
– jmacedo
Sep 27 at 19:16
@jmacedo Yup, that's exactly correct. It's easy to get confused about because base64 data certainly looks encrypted, which is even more true when you realize that a lot of encrypted data is actually displayed in a base64 encoding.
– Conor Mancone
Sep 27 at 19:19
7
It's also certainly possible to put encrypted data into the JWT data, but then it's not the JWT hiding it.
– Bobson
Sep 29 at 0:06
7
This answer assumes that all JWT are (unencrypted) JWS. It may be useful to mention JWE (which are a valid representation of JWT, and are supported by many of the same libraries). (@Bobson - if one uses JWE, then it is the JWT/JWE spec that defines the encryption hiding it.)
– Bob
Sep 29 at 17:09
4
Sorry, but I have to -1 because encrypted JWTs (using the JWE format) are quite common in the applications I work with. This would be a stronger answer if you mentioned that the OP is seeing that behaviour because their JWTs are signed (with an HMAC signature), but in general a JWT can be signed, or encrypted, or both, or neither.
– Mike Ounsworth
Sep 29 at 21:26
|
show 1 more comment
tl/dr: Your selected version of the JWT doesn't encrypt anything, it merely encodes it for easy
transport. The data in the payload is not meant to be a secret.
You have a JWS (JWT with signature). What you are looking at is simply the base64 encoded data payload. A JWS contains 3 parts:
- The base64 encoded header
- The base64 encoded data
- A cryptographic signature
Base64 is simply an encoding format - not any kind of encryption, and is not meant to hide the data. Rather, it just makes sure it is composed solely of standard ASCII characters that easily survive transfer between different systems. As a result, if you were to take everything in between the two periods and run it through a base64 decoder, you would see your original payload data without issue.
The key therefore is simple: a JWS isn't meant to hide the data. It is simply intended (through the signature) to ensure data integrity, i.e. if someone changes the data payload then you will know because your signature will no longer match.
Alternately you could use a JWE (JWT with encryption) to hide your data. See Bob's excellent answer for a more detailed comparison between JWT, JWS, and JWE, all of which are closely related.
Of course. Thanks. I had this misconception in my mind that the jwt could only be read by those having the secret, but it turns out that it's just a vehicle for information which we need to make sure came from a legitimate source.
– jmacedo
Sep 27 at 19:16
@jmacedo Yup, that's exactly correct. It's easy to get confused about because base64 data certainly looks encrypted, which is even more true when you realize that a lot of encrypted data is actually displayed in a base64 encoding.
– Conor Mancone
Sep 27 at 19:19
7
It's also certainly possible to put encrypted data into the JWT data, but then it's not the JWT hiding it.
– Bobson
Sep 29 at 0:06
7
This answer assumes that all JWT are (unencrypted) JWS. It may be useful to mention JWE (which are a valid representation of JWT, and are supported by many of the same libraries). (@Bobson - if one uses JWE, then it is the JWT/JWE spec that defines the encryption hiding it.)
– Bob
Sep 29 at 17:09
4
Sorry, but I have to -1 because encrypted JWTs (using the JWE format) are quite common in the applications I work with. This would be a stronger answer if you mentioned that the OP is seeing that behaviour because their JWTs are signed (with an HMAC signature), but in general a JWT can be signed, or encrypted, or both, or neither.
– Mike Ounsworth
Sep 29 at 21:26
|
show 1 more comment
tl/dr: Your selected version of the JWT doesn't encrypt anything, it merely encodes it for easy
transport. The data in the payload is not meant to be a secret.
You have a JWS (JWT with signature). What you are looking at is simply the base64 encoded data payload. A JWS contains 3 parts:
- The base64 encoded header
- The base64 encoded data
- A cryptographic signature
Base64 is simply an encoding format - not any kind of encryption, and is not meant to hide the data. Rather, it just makes sure it is composed solely of standard ASCII characters that easily survive transfer between different systems. As a result, if you were to take everything in between the two periods and run it through a base64 decoder, you would see your original payload data without issue.
The key therefore is simple: a JWS isn't meant to hide the data. It is simply intended (through the signature) to ensure data integrity, i.e. if someone changes the data payload then you will know because your signature will no longer match.
Alternately you could use a JWE (JWT with encryption) to hide your data. See Bob's excellent answer for a more detailed comparison between JWT, JWS, and JWE, all of which are closely related.
tl/dr: Your selected version of the JWT doesn't encrypt anything, it merely encodes it for easy
transport. The data in the payload is not meant to be a secret.
You have a JWS (JWT with signature). What you are looking at is simply the base64 encoded data payload. A JWS contains 3 parts:
- The base64 encoded header
- The base64 encoded data
- A cryptographic signature
Base64 is simply an encoding format - not any kind of encryption, and is not meant to hide the data. Rather, it just makes sure it is composed solely of standard ASCII characters that easily survive transfer between different systems. As a result, if you were to take everything in between the two periods and run it through a base64 decoder, you would see your original payload data without issue.
The key therefore is simple: a JWS isn't meant to hide the data. It is simply intended (through the signature) to ensure data integrity, i.e. if someone changes the data payload then you will know because your signature will no longer match.
Alternately you could use a JWE (JWT with encryption) to hide your data. See Bob's excellent answer for a more detailed comparison between JWT, JWS, and JWE, all of which are closely related.
edited Sep 30 at 12:07
answered Sep 27 at 18:43
Conor ManconeConor Mancone
19.9k8 gold badges58 silver badges72 bronze badges
19.9k8 gold badges58 silver badges72 bronze badges
Of course. Thanks. I had this misconception in my mind that the jwt could only be read by those having the secret, but it turns out that it's just a vehicle for information which we need to make sure came from a legitimate source.
– jmacedo
Sep 27 at 19:16
@jmacedo Yup, that's exactly correct. It's easy to get confused about because base64 data certainly looks encrypted, which is even more true when you realize that a lot of encrypted data is actually displayed in a base64 encoding.
– Conor Mancone
Sep 27 at 19:19
7
It's also certainly possible to put encrypted data into the JWT data, but then it's not the JWT hiding it.
– Bobson
Sep 29 at 0:06
7
This answer assumes that all JWT are (unencrypted) JWS. It may be useful to mention JWE (which are a valid representation of JWT, and are supported by many of the same libraries). (@Bobson - if one uses JWE, then it is the JWT/JWE spec that defines the encryption hiding it.)
– Bob
Sep 29 at 17:09
4
Sorry, but I have to -1 because encrypted JWTs (using the JWE format) are quite common in the applications I work with. This would be a stronger answer if you mentioned that the OP is seeing that behaviour because their JWTs are signed (with an HMAC signature), but in general a JWT can be signed, or encrypted, or both, or neither.
– Mike Ounsworth
Sep 29 at 21:26
|
show 1 more comment
Of course. Thanks. I had this misconception in my mind that the jwt could only be read by those having the secret, but it turns out that it's just a vehicle for information which we need to make sure came from a legitimate source.
– jmacedo
Sep 27 at 19:16
@jmacedo Yup, that's exactly correct. It's easy to get confused about because base64 data certainly looks encrypted, which is even more true when you realize that a lot of encrypted data is actually displayed in a base64 encoding.
– Conor Mancone
Sep 27 at 19:19
7
It's also certainly possible to put encrypted data into the JWT data, but then it's not the JWT hiding it.
– Bobson
Sep 29 at 0:06
7
This answer assumes that all JWT are (unencrypted) JWS. It may be useful to mention JWE (which are a valid representation of JWT, and are supported by many of the same libraries). (@Bobson - if one uses JWE, then it is the JWT/JWE spec that defines the encryption hiding it.)
– Bob
Sep 29 at 17:09
4
Sorry, but I have to -1 because encrypted JWTs (using the JWE format) are quite common in the applications I work with. This would be a stronger answer if you mentioned that the OP is seeing that behaviour because their JWTs are signed (with an HMAC signature), but in general a JWT can be signed, or encrypted, or both, or neither.
– Mike Ounsworth
Sep 29 at 21:26
Of course. Thanks. I had this misconception in my mind that the jwt could only be read by those having the secret, but it turns out that it's just a vehicle for information which we need to make sure came from a legitimate source.
– jmacedo
Sep 27 at 19:16
Of course. Thanks. I had this misconception in my mind that the jwt could only be read by those having the secret, but it turns out that it's just a vehicle for information which we need to make sure came from a legitimate source.
– jmacedo
Sep 27 at 19:16
@jmacedo Yup, that's exactly correct. It's easy to get confused about because base64 data certainly looks encrypted, which is even more true when you realize that a lot of encrypted data is actually displayed in a base64 encoding.
– Conor Mancone
Sep 27 at 19:19
@jmacedo Yup, that's exactly correct. It's easy to get confused about because base64 data certainly looks encrypted, which is even more true when you realize that a lot of encrypted data is actually displayed in a base64 encoding.
– Conor Mancone
Sep 27 at 19:19
7
7
It's also certainly possible to put encrypted data into the JWT data, but then it's not the JWT hiding it.
– Bobson
Sep 29 at 0:06
It's also certainly possible to put encrypted data into the JWT data, but then it's not the JWT hiding it.
– Bobson
Sep 29 at 0:06
7
7
This answer assumes that all JWT are (unencrypted) JWS. It may be useful to mention JWE (which are a valid representation of JWT, and are supported by many of the same libraries). (@Bobson - if one uses JWE, then it is the JWT/JWE spec that defines the encryption hiding it.)
– Bob
Sep 29 at 17:09
This answer assumes that all JWT are (unencrypted) JWS. It may be useful to mention JWE (which are a valid representation of JWT, and are supported by many of the same libraries). (@Bobson - if one uses JWE, then it is the JWT/JWE spec that defines the encryption hiding it.)
– Bob
Sep 29 at 17:09
4
4
Sorry, but I have to -1 because encrypted JWTs (using the JWE format) are quite common in the applications I work with. This would be a stronger answer if you mentioned that the OP is seeing that behaviour because their JWTs are signed (with an HMAC signature), but in general a JWT can be signed, or encrypted, or both, or neither.
– Mike Ounsworth
Sep 29 at 21:26
Sorry, but I have to -1 because encrypted JWTs (using the JWE format) are quite common in the applications I work with. This would be a stronger answer if you mentioned that the OP is seeing that behaviour because their JWTs are signed (with an HMAC signature), but in general a JWT can be signed, or encrypted, or both, or neither.
– Mike Ounsworth
Sep 29 at 21:26
|
show 1 more comment
What you're missing is that your token is signed (or, more precisely, authenticated with a symmetric key) but not encrypted.
If you take the token in your question above, split it into three pieces at the periods (.
) and feed each piece into a base64 decoder, you'll get the following decoded outputs:
"alg":"HS256","typ":"JWT"
"sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
and a sequence of 32 mostly non-ASCII bytes which is the 256-bit HMAC authentication tag for the rest of the token. As you can see, all the data is there easily readable by anyone. The authentication tag only prevents anyone who doesn't know the secret HMAC key from modifying the token or creating forged tokens from scratch.
add a comment
|
What you're missing is that your token is signed (or, more precisely, authenticated with a symmetric key) but not encrypted.
If you take the token in your question above, split it into three pieces at the periods (.
) and feed each piece into a base64 decoder, you'll get the following decoded outputs:
"alg":"HS256","typ":"JWT"
"sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
and a sequence of 32 mostly non-ASCII bytes which is the 256-bit HMAC authentication tag for the rest of the token. As you can see, all the data is there easily readable by anyone. The authentication tag only prevents anyone who doesn't know the secret HMAC key from modifying the token or creating forged tokens from scratch.
add a comment
|
What you're missing is that your token is signed (or, more precisely, authenticated with a symmetric key) but not encrypted.
If you take the token in your question above, split it into three pieces at the periods (.
) and feed each piece into a base64 decoder, you'll get the following decoded outputs:
"alg":"HS256","typ":"JWT"
"sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
and a sequence of 32 mostly non-ASCII bytes which is the 256-bit HMAC authentication tag for the rest of the token. As you can see, all the data is there easily readable by anyone. The authentication tag only prevents anyone who doesn't know the secret HMAC key from modifying the token or creating forged tokens from scratch.
What you're missing is that your token is signed (or, more precisely, authenticated with a symmetric key) but not encrypted.
If you take the token in your question above, split it into three pieces at the periods (.
) and feed each piece into a base64 decoder, you'll get the following decoded outputs:
"alg":"HS256","typ":"JWT"
"sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022
and a sequence of 32 mostly non-ASCII bytes which is the 256-bit HMAC authentication tag for the rest of the token. As you can see, all the data is there easily readable by anyone. The authentication tag only prevents anyone who doesn't know the secret HMAC key from modifying the token or creating forged tokens from scratch.
answered Sep 27 at 18:44
Ilmari KaronenIlmari Karonen
3,03714 silver badges23 bronze badges
3,03714 silver badges23 bronze badges
add a comment
|
add a comment
|
Thanks for contributing an answer to Information Security Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f218801%2fshould-i-be-able-to-see-patterns-in-a-hs256-encoded-jwt%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
Just for completeness, JWT can use encryption as defined by JWE, however in your case (
alg=HS256
) it is a JWS (signature) instead.– eckes
Sep 28 at 15:32
@eckes is correct. tools.ietf.org/html/rfc7518#section-5.1
– Adam Williams
Sep 29 at 16:33
3
@Bob has a more complete answer than mine. I think you should accept his instead.
– Conor Mancone
Sep 29 at 23:38