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

body and footer questions #83

Closed
veqryn opened this issue Jul 12, 2018 · 4 comments
Closed

body and footer questions #83

veqryn opened this issue Jul 12, 2018 · 4 comments

Comments

@veqryn
Copy link

veqryn commented Jul 12, 2018

I became interested in your paseto standard after feeling a bit uneasy about JWT's, but I have a few questions and wasn't sure how else to ask but to make a github issue (feel free to add the answers to your documentation).

  1. Is the body and its claims always encrypted? If not, when it is it not encrypted?

  2. Is the footer always unencrypted?

  3. Is the footer signed?

  4. If you want the website frontend to see certain claims or data, would you advise putting that in a json objected in the footer, instead of into the body?

  5. Is the footer validated against anything? Or is it just a grab bag of whatever I want to put in it, including nothing?

  6. Which claims are "built into the standard" and are expected to be validated or read by the implementing libraries?

  7. Should Paseto be used for sending session id's and non-confidential data about the user to the website frontend, to be stored in secure cookies? (ie: what most people use JWT's for)

@paragonie-scott
Copy link
Member

paragonie-scott commented Jul 13, 2018

  1. Is the body and its claims always encrypted? If not, when it is it not encrypted?

As documented here, the body is encrypted for v1.local, v2.local, ...

Local-scoped tokens means that the issuer is also the verifier, and you're storing encrypted data.

Public-scoped tokens means that the issuer is a third party, and therefore the contents are only needed to be signed.

  1. Is the footer always unencrypted?

Yes.

  1. Is the footer signed?

Yes, it is always authenticated.

  1. If you want the website frontend to see certain claims or data, would you advise putting that in a json objected in the footer, instead of into the body?

From the documentation:

Thus, if you want unencrypted, but authenticated, tokens, you can simply set your payload to an empty string and your footer to the message you want to authenticate.

Conversely, if you want to support key rotation, you can use the unencrypted footer to store the Key-ID.

If you want data to be unencrypted, but signed, in a local-only environment, you can dump everything in the footer and the payload can be empty.

  1. Is the footer validated against anything? Or is it just a grab bag of whatever I want to put in it, including nothing?

For local tokens, it is included in the authentication tag attached to the ciphertext. For public tokens, it's included in the signature calculation. This prevents attacks based on footer truncation or malleability.

However, beyond that, you can do whatever you want with it.

  1. Which claims are "built into the standard" and are expected to be validated or read by the implementing libraries?

This was being documented in the RFC draft. The Markdown source is available online, but at some point the compiled .txt output was erroneously removed from the Git repository. (Note to self: Re-add this.)

I've copied the table below in case the RFC changes so you can have a point-in-time copy for future reference:

Registered Claims

The following keys are reserved for use within PASETO. Users SHOULD NOT
write arbitrary/invalid data to any keys in a top-level PASETO in the list
below:

Key Name Type Example
iss Issuer string {"iss":"paragonie.com"}
sub Subject string {"sub":"test"}
aud Audience string {"aud":"pie-hosted.com"}
exp Expiration DtTime {"exp":"2039-01-01T00:00:00+00:00"}
nbf Not Before DtTime {"nbf":"2038-04-01T00:00:00+00:00"}
iat Issued At DtTime {"iat":"2038-03-17T00:00:00+00:00"}
jti Token ID string {"jti":"87IFSGFgPNtQNNuw0AtuLttP"}
kid Key-ID string {"kid":"stored-in-the-footer"}

In the table above, DtTime means an ISO 8601 compliant DateTime string.
See [#keyid-support] for special rules about kid claims.

Any other claims can be freely used. These keys are only reserved in the
top-level JSON object.

The keys in the above table are case-sensitive.

Implementors (i.e. library designers) SHOULD provide some means to
discourage setting invalid/arbitrary data to these reserved claims.

For example: Storing any string that isn't a valid ISO 8601 DateTime in the
exp claim should result in an exception or error state (depending on the
programming language in question).

We prefer ISO 8601 over UNIX Timestamps because of i18n and timezone issues.

  1. Should Paseto be used for sending session id's and non-confidential data about the user to the website frontend, to be stored in secure cookies? (ie: what most people use JWT's for)

See Was "Stateless Session Tokens" one of Paseto's Design Goals? from the documentation.

@veqryn
Copy link
Author

veqryn commented Jul 13, 2018

Thanks for the answers.
I have a clarification to ask and a couple more questions:

Should Paseto be used for sending session id's and non-confidential data about the user to the website frontend, to be stored in secure cookies? (ie: what most people use JWT's for)

See Was "Stateless Session Tokens" one of Paseto's Design Goals? from the documentation.

Question 7 above was actually about stateful session tokens.
Right now we are using JWT's to store what is basically a session id and some non-confidential data about the client that is useful to the front end browser. The id is just a key-id or jid that looks up a key and a reference to the customer in a table. The other data includes the customer name, id, audience, etc. The JWT gets stored in secure cookies.
Is this a good application for Paseto to replace JWT in?

Is the body and its claims always encrypted? If not, when it is it not encrypted?

As documented here, the body is encrypted for v1.local, v2.local, ...
Local-scoped tokens means that the issuer is also the verifier, and you're storing encrypted data.
Public-scoped tokens means that the issuer is a third party, and therefore the contents are only needed to be signed.

Why are local-scoped tokens always encrypted, and public-scoped tokens unencrypted?
Wouldn't it make more sense to have both an encrypted section (you call it the body right now) and an unencrypted section (you call it the footer currently) for both local and public tokens? There is no reason why a public token couldn't use asymmetric encryption on the body, and I'm sure some people would want that.

I also feel it would make more sense to call them symmetric and asymmetric tokens (ie: v2.sym.<...>, and v1.asym.<...>), as the words local and public can be a bit misleading.

Is the footer validated against anything? Or is it just a grab bag of whatever I want to put in it, including nothing?

For local tokens, it is included in the authentication tag attached to the ciphertext. For public tokens, it's included in the signature calculation. This prevents attacks based on footer truncation or malleability.
However, beyond that, you can do whatever you want with it.

Right now the body is JSON, while the footer is just whatever.
I highly suggest for v3 that you make the footer mandatory JSON as well.
One of the biggest things I see people using JWT's for is adding additional claims to be read by the browser. Having the footer be JSON will make that a lot easier!

Can I also suggest that those validated registered claims be allowed to appear in the footer instead of the body?
In other words, the implementations should look for those claims (ex: exp) in the body, and if any aren't there then it also looks for those claims in the footer.

thanks!

@paragonie-scott
Copy link
Member

Is this a good application for Paseto to replace JWT in?

Neither standard was designed for this use-case, and it's dangerous to use JWT this way. At least with PASETO you can reduce your risk to protocol vulnerabilities, but the fundamental lack of revocation is still a problem.

Why are local-scoped tokens always encrypted, and public-scoped tokens unencrypted?

Because for a local-scoped token (i.e. the issuer is the verifier), where the end user is basically a data mule for an opaque ciphertext blob, it makes sense to encrypt.

For claims signed by a third party, adding public-key encryption adds a ton of overhead to the protocol. How do you ensure the third-party uses the correct public key? Do you sign-then-encrypt, or encrypt-then-sign?

If we wanted to solve the 100% problem, sure, we could bolt public-key encryption into the protocol, but almost nobody needs it.

@paragonie-security
Copy link
Contributor

Public-key encryption is solved in PASERK.

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

3 participants