What are the pros/cons of using JWE or JWS [closed] - api

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm trying to implement an authentication token system, so I want to know the pros/cons of using JSON Web Encryption (JWE) or JSON Web Signature (JWS), and if it make sense to use both (a JWE inside a JWS).

JSON Web Signature (JWS) claims are signed with a signature that can be verified by the server with a secret signing key. This ensures that the claims have not been tampered with when passed between client and server. The contents of JWS token are Base64 encoded and not encrypted (remember encoding is different from encryption!). Base64 encoded data looks encrypted in that it looks like a garbage text but it’s actually trivial to turn back into readable data. Therefore it is always advised to not store any sensitive information in JWT. It is advisable to use JWT only when you want to exchange information between two parties (or between client and server) and no sensitive data is passed as payload in token.
But what if you want to include any private information in a token? You don’t want your sensitive information to be present in a token that is only Base64 encoded that can be easily decoded by any attacker. Fortunately, there is a way to encrypt and guard the claims data with another, a more secure level of protection known as JSON Web Encryption (JWE). It defines a way to encrypt your claims data (which is basically JSON based data structure) so that only intended receiver can read the information present in a token.
The best way to handle a web token is to:
Sign it, so that it is well known that the token originated from authorized client.
Encrypt it, so that only an authorized server can tell what it says.
We have couple of good libraries available in Java that can encrypt your JSON Web Token:
Jose4J
Nimbus-JOSE-JWT
Both the above libraries are open source (Apache 2.0) implementation of JWT and JOSE (Javascript Object Signing and Encryption) specification suite. They both are quality libraries and you can’t really make a wrong choice. However, JWT.IO has a nice UI to show differences of each available library.

A JWS is used to sign the data, making it integrity-protected, this means that:
Man-in-the-middle attacks can see the data for what it is
Man-in-the-middle attacks cannot modify it, since the signature verification would fail
A JWE is used to encrypt the data as well as make it integrity-protected
Man-in-the-middle attacks cannot see the data for what it is
Man-in-the-middle attacks cannot modify it, since the verification would fail

The aims between JWS and JWE are different.
A JWS is used to sign claims, a JWE is used to transmit sensitive data.
If you want to implement an authentication system, then JWS must be used to verify authenticity of claims.
You can also encrypt your JWS using JWE if some of the claims in your JWS contain sensitive information.
But use only JWE is a none sense in your context.

Related

Securing a JWT token

In general, JWT has an encoded message with a signature. The signature uses for checking the genuinity of the data. My question is, this signature is for assuring the client about the server, but how server can trust the client? In other words, if a client sends a JWT to the server, how the server can be sure this is the right/authenticated client?
My second question is about JWT's lifetime. I know there is a claim (exp) which can be set to indicate JWT's expiry. But what if the client changes that claim? Should I keep expiry date on the server to make sure the JWT is still valid? Wikipedia says: To validate the session stored in the token is not revoked, token assertions must be checked against a data store. This renders the tokens no longer stateless, undermining the primary advantage of JWTs.
Given a JWT, the server knows that the client is legitimate by verifying that the HMAC of the header and payload is equal to the signature. The server has a secret key that it uses when computing the HMAC, so if someone wanted to create a fake JWT with a proper signature, they would need to have access to this key.
Your second question shares the same idea as the first. If a client wanted to change the expiration of their JWT, they would have to recompute the signature, and to do this successfully, they'd have to know the secret key.
The point of using JWTs is not to store data like the expiration date on the server, all of this data lives inside the token itself, and the integrity of this data is protected by the secret key used to compute the signature.
JSON web token (JWT) can come in two flavours. Typical, the most widely used form is to use JWT with a JSON web signature (JWS). In security world, this provide integrity. Other form is JWT with JSON web encryption (JWE). This form provides both integrity and confidentiality.
So if you have a specific requirement to identify that you get a valid, condifential JWT, then you should adopt JWE based approach. You can read more about this in RFC7516. For encryption, you can use either symmetric or asymmetric keys. Once you receive JWE based JWT, you can validate that it was sent by intended party by successful decryption of the JWT payload.

Are Json Web Tokens secure enough? And how to secure payload?

When I go to https://jwt.io I see this encoded token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
If I go to https://codebeautify.org/base64-decode , copy-paste token value and push Decode, I get this:
{"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"John Doe","iat":1516239022}
If I switch from HS256 to RS256, I now get this token:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.TCYt5XsITJX1CxPCT8yAV-TVkIEq_PbChOMqsLfRoPsnsgw5WEuts01mq-pQy7UJiN5mgRxD-WUcX16dUEMGlv50aqzpqh4Qktb3rk-BuQy72IFLOqV0G_zS245-kronKb78cPN25DGlcTwLtjPAYuNzVBAh4vGHSrQyHUdBBPM
And it also can be easily decoded with base64. So, my question is, whether it is expected behaviour or not? And if yes, what is the reason to use different algorithms (HS256, RS256 etc.), if whatever algorithm we use, we can easily read the contents using just base64 decode?
Well Jwt is not meant to secure the content it is used to verify a claim, ie when you sign a request using jwt, when decoding it the user/sytem must have the secret key. So to answer your question yes it is the expected behaviour, the base 64 encoding is only meant for transportation over the URL and not to secure it. The last bit if i may clarify the verification of a claim is simply to mean you are what/who you tell the system you are and that the content of the signature has not been altered even alittle bit, any changes to any part of the encoded signature will result to signature failure; hence the claim would nolonger be authentic or true. To see this just try to encode something like this in your terminal
import jwt
encoded=jwt.encode({'name':'some name'}, 'somesecretkey',algorithm='HS256')
then copy the resulting token and then remove or add asingle letter to the string and try decoding using the same secret key and watch it fail or try the same at codebeautify again

Where should I store access tokens and refresh tokens?

I have some questions related to tokens and encryption.
First of all Access Tokens :
Regardless the various attacks(that you need to bear in mind so that you take measures against), would you recommend storing an access token on the client?(localstorage/ cookies).
If yes, will I need to encrypt it and store the encrypted token on the client. However, is that really needed since I am using SSL? You are using SSL to prevent a MIM attack.But since you are using HTTPS, why should we also encrypt the access token?
My second question is related to encryption. For SSL, I understand that I need a certificate (or self-signed certificate to test it locally). However, for encrypting the token, do I need the same SSL's certificate, or can I use an RSACryproProvider to generate a pair of public/private keys?
For Refresh tokens :
I believe the best approach is to save the encrypted refresh tokens in the database. It could be an actual API that reads/Writes refresh tokens in the database. However, the refresh token, must be stored along with some user attribute ie UserId, so you can retrieve it based on i.e userid, email etc. Assuming, I use the UserId, I would encrypt it along with some character and date and store it on the client. Do you agree on that? And also, I am thinking to restrict the access on that API, so that it can only serve requests from a particular server or servers (web farm). What is your opinion about this approach?
I would REALLY appreciate your help, as I am really trying to understand in depth some concepts. If there is something, I don't express correctly, please let me know to rephrase my question.
Thanks

REST API authentication with query string encryption

I am building a web application that provides an API as it's primary function. I have been looking into methods for authentication but have been struggling to make a decision on what to use.
Since this will be a paid service and the API is the service, I need to make it as easy to use as possible so as not to put people off but obviously I want it to be secure. I have considered using HTTP basic authentication over SSL but would like to avoid the costs/overheads/hassle of SSL if possible early on and maybe provide it as an option later.
I like the AWS style API authentication (see here) but the problem is I can't have users sending the query string as plain text along with a signature because the parameters may contain things like phone numbers which I think customers would rather not expose. I have thought about providing a secret key to encrypt the string which is sent along with an api key to identify the user.
What do you think the best option is to also encrypt the query string along with the request while maintaining simplicity?
Use HTTPS. It's simple, supported by almost all client libraries, trusted, secure, and it protects the URL and payload.

What is an API key? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I see this word in almost every cross service application these days.
What exactly is an API key and what are its uses?
Also, what is the difference between public and private API keys.
What "exactly" an API key is used for depends very much on who issues it, and what services it's being used for. By and large, however, an API key is the name given to some form of secret token which is submitted alongside web service (or similar) requests in order to identify the origin of the request. The key may be included in some digest of the request content to further verify the origin and to prevent tampering with the values.
Typically, if you can identify the source of a request positively, it acts as a form of authentication, which can lead to access control. For example, you can restrict access to certain API actions based on who's performing the request. For companies which make money from selling such services, it's also a way of tracking who's using the thing for billing purposes. Further still, by blocking a key, you can partially prevent abuse in the case of too-high request volumes.
In general, if you have both a public and a private API key, then it suggests that the keys are themselves a traditional public/private key pair used in some form of asymmetric cryptography, or related, digital signing. These are more secure techniques for positively identifying the source of a request, and additionally, for protecting the request's content from snooping (in addition to tampering).
Very generally speaking:
An API key simply identifies you.
If there is a public/private distinction, then the public key is one that you can distribute to others, to allow them to get some subset of information about you from the api. The private key is for your use only, and provides access to all of your data.
It looks like that many people use API keys as a security solution. The bottom line is: Never treat API keys as secret it is not. On https or not, whoever can read the request can see the API key and can make whatever call they want. An API Key should be just as a 'user' identifier as its not a complete security solution even when used with ssl.
The better description is in Eugene Osovetsky link to: When working with most APIs, why do they require two types of authentication, namely a key and a secret?
Or check http://nordicapis.com/why-api-keys-are-not-enough/
An API key is a unique value that is assigned to a user of this service when he's accepted as a user of the service.
The service maintains all the issued keys and checks them at each request.
By looking at the supplied key at the request, a service checks whether it is a valid key to decide on whether to grant access to a user or not.
API keys are just one way of authenticating users of web services.
Think of it this way, the "Public API Key" is similar to a user name that your database is using as a login to a verification server. The "Private API Key" would then be similar to the password. By the site/databse using this method, the security is maintained on the third party/verification server in order to authentic request of posting or editing your site/database.
The API string is just the URL of the login for your site/database to contact the verification server.