Should jwt web token be encrypted? - encryption

I was reading article on JWT web token as an access token that is being response to the user. Some of it mention that the web token should be able to be decoded by the user.
Does it means that it is not a good practice to decrypt the entire web token? For example, I suppose to return following JWT web token to user where this piece of information can be decoded.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
However, I feel that I do not want to let user able to decode his/her access token, so I use another encryption algorithm to encrypt everything into another form as follow and pass back to user.
So, I would decrypt this new text when I'll get this access token in the server and decode it.
Is it recommended to do it this way if I do not wish to expose some of the value available in claim (such as user id) to the user? If not, what are the alternatives?

JWT (RFC7519) is just a compact way to safely transmit claims from an issuer to the audience over HTTP.
JWT can be:
signed (JWS - RFC7515)
encrypted (JWE - RFC7516)
signed then encrypted (this order is highly recommended). The whole JWS is the payload of the JWE
encrypted then signed.
It makes sense to encrypt a JWS if you want to keep sensitive information hidden from the bearer (client) or third parties.
The real questions are: does the audience support JWE? If yes, which algorithms are supported?

JWT are "signed" and therefore its contents are protected from tampering: you cannot change its contents without invalidating them.
You can optionally "encrypt" the contents and therefore turn them visible only to issuer (the entity creating the token) and the consumer (the entity that is destined to use its contents after verification).
There's a standard for that: JWE

A token contains user data and acts like a temp storage. It is not good to store sensitive data in a token.
At the first level, you should store the user name and maybe role or something like that. You should not include passwords, so it does not need to be encrypted.
Nevertheless, you can encrypt it if you want.

Yes, the best practice is use the JSON Web Encryption (JWE) RFC, the claims in the JWT after decode it are in plain text, so if the user lost the token, the sensitive information as email, username, access permissions can be visible and can be used as a the initial information of any attack.

Related

How are authorization tokens stored / recreated by the browser?

I am Looking at the Network activity of this page: https://helm.csod.com/ux/ats/careersite/4/home?c=helm&lang=de-DE.
Specifically at the post request with the Name: "search". Its using an authorization token.
tldr: How is the following authorization token stored on the Client side?
Goal:
I would like to understand how the browser (client-side) stores this authorization token. I dont Need to get the data or know how to scrape with selenium or sthg. I would just be interested in the mechanics behind.
What i tried:
I find the token in the page source: view-source:https://helm.csod.com/ux/ats/careersite/4/home?c=helm&lang=de-DE.
It seems like there is an object csod created in /player-career-site/1.15.4/pages/home.js.
then the key is stored in csod.context.
Finally, csod.player.initialize(csod.context) is called.
Unfortunately, i failed digging in the Code and finding These function as there where too many Matches for initialize and my js are skills too bad.
As storage i am only Aware of the Cookies. It might be transformed / encrypted and stored in the cookies? But how is it then restored to the "original" token, before being added to the request Header?
This seems to be a CSRF prevent method.
The token is created with a key in the back end, it stores the original key in a session and sends the token to the client side.
When the client sends a request, the token is posted with the data as a header or with the data, then the back end gets the stored key in the session, generate the token with the same method and compare it with the posted token. If they are equal there is no problem, access granted.
It is not necessary to restore as you can't decrypt that depending on the algorithm (sha256, md5, etc)
And the browser don't do that, as it can be manipulated, there is no sense to.
The token sent here is JWT(JSON Web Token). This is a widely used standard authentication mechanism.
You can create your own token in any languages like JS, Java, PHP, Python, etc.
I am adding a basic authentication flow:
Let's say a user comes on a form. Enter his email & password.
Now an HTTP request is being sent to the server with credentials. The backend server checks the details and if successful, then returns a response containing the authentication token.
Most of the time this token is stored in localstorage and sometimes in cookies.
Now for every request the token is picked from the stored location and sent in the header.
On the backend, it is checked if the request header has the details or not. And then respond accordingly.
At last, whenever someone logs out then that token is removed from the front end.
I hope it helps! Let me know if you have any queries

Is JWT in URI a bad practice?

I have a backlist of tokens (JWT) stored in Redis and would like to enable users of my website to blacklist their tokens in a RESTful way.
I can either:
Build the route /sessions/<token> with a DELETE method
Build the route /sessions/ with a DELETE method and the token sent in the request body.
The first solution is simple but the token is stored in the server's logs and in the user's browser's history.
The second solution seems better but I'm not sure I'm not breaking HTTP RFC's idempotency principle by sending a DELETE request with a body.
What's the best practice in this case?
Is JWT in URI a bad practice?
JWT tokens are URL-safe when it comes to the syntax. From the RFC 7519:
A JWT is represented as a sequence of URL-safe parts separated by period (.) characters. Each part contains a base64url-encoded value. [...]
However, when using JWT as bearer tokens, it's advisable to avoid sending them in the URL. See the following quote from the RFC 6750:
Don't pass bearer tokens in page URLs: Bearer tokens SHOULD NOT be
passed in page URLs (for example, as query string parameters).
Instead, bearer tokens SHOULD be passed in HTTP message headers or
message bodies for which confidentiality measures are taken.
Browsers, web servers, and other software may not adequately secure
URLs in the browser history, web server logs, and other data
structures. If bearer tokens are passed in page URLs, attackers might
be able to steal them from the history data, logs, or other unsecured
locations.
For the situation mentioned in your question, you may not need to send the full token. You could give the token a unique identifier (stored in the jti claim) and then send only the token identifier to the server.
See how the jti claim is defined in the above mentioned RFC:
4.1.7. "jti" (JWT ID) Claim
The jti (JWT ID) claim provides a unique identifier for the JWT.
The identifier value MUST be assigned in a manner that ensures that
there is a negligible probability that the same value will be
accidentally assigned to a different data object; if the application
uses multiple issuers, collisions MUST be prevented among values
produced by different issuers as well. The jti claim can be used
to prevent the JWT from being replayed. The jti value is a case-
sensitive string. Use of this claim is OPTIONAL.
A UUID should be unique enough to identify your tokens without collisions.
You don't need to store the full token in the blacklist either: store only the value of the jti claim and some other claims that you may find relevant (such as sub and exp, for example).
DELETE requests shouldn't contain a body. So you could use DELETE /sessions/{id}, where {id} is the unique identifier of your token.

OAuth access token and refresh token creation

I'm implementing my own OAuth authentication system (with refresh_token support) for an app and I have some questions about how to do it:
Client identification: The client is registered in the auth server and gets a client_id and a client_secret. How do I generate it? is there some kind of relation between both values?.
User authentication: The client sends the users_credentials (username+password for example) + client_id and gets a refresh_token and (temp?)access_token. That access_token is the one I should use in further request or I should use a accesss_token`=F(refresh_token,access_token,client_secret). In the second case what does the F function consist on?
Access token refresh: The client send client_id, refresh_token and gets a access_token (and a optional new refresh_token). Does the access_token need the same conversion (whatever it be), as in the point 2?
If I'm wrong, when and how is the client_secret used?
Complete answers and concrete examples will be "bountied".
The authorisation/authentication server generates these values when you create an account with them (for instance when you create a developer account with Facebook or Google). If you are doing these parts yourself, they should be cryptographically secure pseudo-random numbers or letters. Remember that the client ID is usually publically visible, so choose a reasonably large set of alpha-numerics (I use 30 characters). The secret is private and can be harder to guess so I chose 30 digits with letters, numbers and symbols. These are not related to each other, it is just that one is public and the other isn't.
The usual way this works is that there is a browser redirect to the auth server passing the client id in the URL (and redirect uri) and specifically NOT the user id and password. The whole point of OAuth2 is that the client system never sees the user name and password, only the auth server. After this redirect, the auth server verifies the client id, checks the username/password (for instance) and then returns to the redirect uri with a temporary code. This temporary code is passed back to the Auth server in order to obtain an access token. Since this call is made as a POST from the server, it also passes the client secret to verify that it really is the correct client system and not someone who stole the client id from somewhere else. At this point, the auth server will return an access token (and optional refresh token - you do not need to use them, I don't).
If the client system wants to log the user in without them having to type in their username and password all the time, it can use a refresh token, if available, to call back onto the Auth server and if the Auth server is happy that the refresh token is still valid and any other business rules are correct, it can give you back another access token directly without the user being involved.
I recommend reading the OAuth2 spec here: OAuth2 Spec RFC6749. It can take a while but if you delete the bits you don't need and reduce the amount of data, there are plenty of useful examples in it.
FIRSTLY, The client identifier can be any string that you want, but it should be unique for each client. It can even be the client's choice if you wish.
The client secret should be a cryptographically strong random string. Here is how you could generate one in C#:
RandomNumberGenerator cryptoRandomDataGenerator = new RNGCryptoServiceProvider();
byte[] buffer = new byte[length];
cryptoRandomDataGenerator.GetBytes(buffer);
string uniq = Convert.ToBase64String(buffer);
return uniq;
SECONDLY, The whole point of OAuth is to allow external apps to do things on your behalf without asking for your credentials. So, you need to implement an authentication server that does the logging in part for you. The user opens the app and gets an option to Log in using your website. You tend out access tokens and refresh tokens once the user has keyed in his credentials. The app can then simply use the tokens to perform actions on the user's behalf. I wrote an answer to How would an efficient OAuth2.0 server / provider work? that explains how access tokens can be constructed.
Remember, the need for refresh tokens and the lifetime of access tokens purely depends on how you intend to use them and what does your security framework look like.
LASTLY, The refresh token can also be an HMAC encoded string/a JSON object as I had explained in the answer to the linked question. You can have random refresh tokens and a large backend storage to keep it to verify the tokens in the incoming requests, or have HMAC encoded strings for added security/less storage requirements/latency to decrypt/encrypt tokens.
Also, do make sure that you go through all the flows and possibly the RFC too as mentioned by Lukos.

Securely store and share a secret with ServiceStack across different logins

Given is a ServiceStack REST Service that can sign documents with one of the public/private key algorithm. The prvate key is encrypted using a passphrase only the admin of this privat/public key pair knows.
Know it should be possible that other logins then the admin can sign documents (authorized by roles, permissions, etc.)
Currently they need to provide the passphrase for the private key in every signature request as the service needs to decrypt the private key and sign the document.
But i dont want to give the private key passphrase to other users and i also don't like to send it on every request over the wire.
So what is the best way to store the passphrase on the service side so that authorized logins can sign documents without knowing and sending the passphrase.
Is there a possibility to store it (automatically encrypted/decrypted from ServiceStack) in the user's session/UserAuth object?
Or is there are any other solution? It should work on .net and mono.
I'd recommend you look at Microsoft's guidance on encrypting/decrypting config sections. This way you can store it encrypted in web.config and your back end service can have access to it.
See http://msdn.microsoft.com/en-us/library/zhhddkxy(v=vs.100).aspx

What's the best way to save user login and password in flex?

What's the best way to save user credentials in flex? Local storage doesn't seem like good place for storing confidential data, because it saves information as a plain text.
You shouldn't. Use browser cookies or a session token to identify the user to the server. For instance:
User enters username and password into a form in Flex and clicks login.
Server validates credentials. Then either in memory or in a database the server associates a random (and sufficiently secure) token with the user. Then the server returns the token to the client.
Client saves the token in either a cookie, LocalSharedObject, or just in memory. Then subsequent requests also include the token.
You can use ExternalInterface to communicate with JavaScript and store data in browser cookies.
Don't store users' name or password in cookies - create a session in the server with credentials in it, and store the session id in the browser cookies.
if your service don't support credential, then the only think you can do is save user login state in SharedObject.
You can save hash value of UserName + Random Token to SharedObject and save a copy of UserName too in SharedObject, then when application created creationComplete check wheather the hash value match with the saved user name.
the good thing about this trick is:
Password never persisted locally.
Harder to fake login because need to
match username with the hash value.
a bit hard to explain here you can check it here, source code is available for download.
User credentials are normally stored in a session variable.
You don't necessarily need to save the credentials as plain text in Local Storage; in fact, Local Storage (SharedObject) is actually serialized as AMF, so it's not plain text to begin with. Whatever medium you use to store your sensitive data, you should certainly consider using some sort of hashing or encryption techniques like SHA1 or RSA.
The difference between hashing and encryption is this:
Hashing (SHA1, MD5, etc) is a one-way encryption - in other words, it's very difficult to determine the original value of the hashed value, so what you can do is compare one hashed value to another since these hashing algorithms will always spit out the same thing.
Encryption (RSA, AES, etc) is a two-way encryption - in other words, you can determine the original value of the encrypted data, usually by using a public/private key combination
It really depends on what you're trying to do.
Hope you come right
SharedObject is a very bad place to store your password in.
Please see this:
http://livedocs.adobe.com/flex/3/html/help.html?content=security2_22.html

Resources