How are Microsoft account JWT authentication tokens signed? - security

In my web application I need to validate the JWT authentication tokens which I get from Live SDK 5.6.
A while ago the signature of those tokens was a HMACSHA256 hash of base64 encoded header+payload using signing key which was the app secret (from account.live.com/developers/applications) + "JWTSig".
It seems that is not the case now.
Does anyone know how are those tokens signed now?
Sorry for my english.

The best way to do this is to get the JWT token returned from Azure Mobile Services and validate it was signed using the same master key from AMS. There is a project on GitHub that shows how to do this:
JWT Validator
This was basically a derivative of another GitHub project that has the original ASP.NET sample here:
AuthenticationTokenSample
The main validation occurs when calling the ValidateSignature() method which takes the bytes of the UTF-8 representation of the JWT Claim segment and calculate an HMAC SHA-256 MAC on them using the shared key from Azure Mobile Services. If the JWT Crypto Segment and the previously calculated value then one has confirmation that the key was used to generate the HMAC on the JWT and that the contents of the JWT Claim Segment have not be tampered with.
The one main thing I found is to remove the appended "JWTSig" string from being appended to the master key in the ValidateSignature() method. It appears the tokens being signed no longer append that string to the master key anymore from AMS. I had all sorts of trouble getting the validation to pass until I removed that segment.

Related

JWT security in OAuth 2.0 and OpenID Connect

I have decided to jump on the bandwaggon and start using OAuth 2.0 and OpenID Connect for the authentication and authorization of my next project, but I'm struggling to understand how a JWT can be secure.
I am using Angular 8 for the front end with a node.js backend and Auth0 as my the identity service provider (the wrong terminology, I know. Forgotten it.)
I have watched two or three PluralSight courses on these subjects but none really go over using the JWT on a node.js back end, mostly they concentrate on the .NET stack which takes a lot of the labour out of it I guess.
My problem is this: how can I be sure that the JWT token sent to my API is one that comes from Auth0? I understand that the token has a signature, and I imagine Auth0 have some private secret they use to sign the JWT, but what is to prevent some malevolent entity creating a JWT with exactly the same content and signing with a different secret and sending that to my API? In the .NET samples I've seen, I see no mention of checking that the signature's secret corresponds to Auth0's. What checks are necessary on the API — .NET, node.js or otherwise — to ensure the JWT is authentic?
And how would this work with nodejs?
I'm not sure if I understood you correctly or what, but JWT is signed and verified by the same secret (if HMAC algo is used), so the answer to your first question would be:
if it's tampered, you will be notified during validation, because signing with a different secret is what gives it away, that the token has been compromised.
Not sure what libraries are you using, but for Node.js, the jsonwebtoken package has a jwt.verify(token, secret) function, that takes in your token and secret values as arguments. This is basically all you need and can have for verification.

Correct Passportjs strategy to use (hash vs jwt)

I have a Laravel app which I'm trying to convert to NodeJS. In the original app we have an API for which access is protected by random generated tokens - assigned to each user and stored in our DB. We automatically generate this secret token when a user first registers then they use it for as long as they would like to use our services. (We verify subscription details for users using these tokens).
I'm trying to replicate the same on NodeJS but I'm a bit lost about the right authentication strategy to use, as passportJS has JSON Web Tokens (JWT) and 'hash'. They both seem correct but I can't figure out the difference and which would be most appropriate in this case.
If hash is the correct strategy would I have to use JWT to generate the token and assign it to each user? Probably I haven't understood properly the concept of hashes and token for authentications. What are the differences between hashes and token for authentication purposes?
I did some more research and found out that the JWT are not exactly what we were using or what we need for our app. We simply create SHA hashes for each user based on personal details and a secret key. This hash is now created and used in the new application correctly. It was simpler than I thought. And for those wanting to learn a bit more about JWT, this Medium article could help a lot:
https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec

Correct Micro Service JWT flow

I am currently building out a micro service architecture and started with the auth server and client. I also wanted to confirm the best flow of authenticating a user with a token.
In the above image. Step 3 is were I start getting confused.
I thought of 2 solutions to the problem.
One every api passes the token to the auth server and waits to get approval that the token stored inside matches the db and it is still valid.
Two is to include a secret phrase in the JWT token and just have the API service parse and check for itself if the token is valid.(The secret phrase would be so that if a hacker tried to fake a token and it parsed to a valid id somehow the phrase would be off without the secret code used to encrypt the token. Which I don't even know if it is possible. If not then I guess 2 would be the best course of action)
A hacker cannot create a valid JWT token if he does not know the the signing key. If he somehow manages to get that signing key it is reasonable to assume that he is able to get your "secret phrase" also.
About the checking: JWT tokens can be checked by the API service as they contain all the information needed (except the signing key that must be known by the API service). The expiration can be checked here also. Anyway, you also need the information stored inside the token, like user ID. You should do this if you want better scalability.
The only reason why you would need to check a JWT token against a third Auth service is to see if it has been invalidated; for this you need a central service although you could replicate the list of invalid tokens to all the API services for better resilience.
You really don't have to forward the request to Auth-server to validate the JWT token. A JWT token is like a bill note, once it's signed it can be validated by anyone who is sharing the key.
I would recommend you to have an edge service in front of all your API-services. The edge service either shares the key by which JWT token is signed by Auth service or has the public key to verify the signature.
Once the signature is verified, the edge service can extract the required information from the token and add it to request header. Your downstream services can consume this information according to their need.
You can use Https to enforce that your request isn't intercepted by anyone over the network. In case, even if someone tries to mess up with the JWT token, the signature won't match and you can detect that. Please go through JWT/KONG: Cannot create JWTs with a shared secret to know more about creating-parsing the JWT token with public-private keys.

Hashing and Encrypting JWT Token

I went through different post here, I am now more confused about how to implement security for tokens. . I currently implemented an authentication serivce (MVC4 + webAPIs) and a relying party (MVC4 app). Relying party (RP) redirects client to Authentication service (AS). AS creates a token, gives it to client. Client gives it to RP. RP adds more claims etc.
THis is what I want to do for securing the token:
HashingToken the token using HMAC SHA 256. How can I share the key between AS and RP? Do I have to sign it and add it in the payload and encrypt?
I want to encrypt the token using AES/Rijndael algorithm/. Again how
can I share the key with RP?
RP will decrypt the token first and decode it with the Algorithm
specified using the key shared to access the payload (timestamp,
audience, issues etc).
I am sliding the token expiry date. there is a field jit which needs
to be unique to avoid replay attacks.. I am currently filling it with
GUID.. I am not sure how to validate/use it in RP
I am currently sharing symmetric keys for hashing & encryption between AS and RP.
I am working on security for the first time.. although I have gone through multiple posts, I am yet to completely understand, and little confused after reading many posts. If someone can help..

How would an efficient OAuth2.0 server / provider work?

I may need to implement an OAuth2.0 server for an API I'm creating. This API would allow 3rd parties to perform actions on the user's behalf.
OAuth2.0 has 3 mains calls. First, there is a call to prompt the user for consent. This returns a code. The second is where the code is exchanged for a access token. Finally, the access token is used to call the API on the user's behalf.
For implementation, I was thinking the first call generates a random string which acts as a code. The code is then stored in a database with a pointer to the current User and a random HMAC Key, then the random data is returned to the 3rd party as the code.
When the 3rd party requests an access token, another piece of random data is generated and concatenated with the code. This string is signed using the HMAC key from Step 1, then this signed string and signature is returned with the signature to form the access token.
When the API call occurs, the hmac key corresponding to the provided access_token is retrieved from the database. The signature of the access_token is verified using the hmac key.
The user can revoke 3rd party access by simply removing an HMAC key from their list of authorized HMAC keys. Furthermore, but just signing random data, I can avoid storing every single access_token every created, and instead maintain a short list of hmac keys.
Anyway, this is my first attempt as thinking through this. Surprisingly, there is little information about implementing the server side of OAuth2.0 efficiently. I would prefer to keep as little information as possible in the database. The advantage of signing random data then later revoking the HMAC key is that I don't have to store every single access token generated by every single authorization call.
Thoughts needed! There has got to be a better way!
EDIT:
I'm NOT looking for an implementation. Thank you though! Also, I assume this whole system will run over HTTPs. Also, I'm talking about the pure OAuth2.0 flow, I'm not talking about OAuth1.0 with signatures and client keys. I'm asking how to design the cryptography behind an OAuth2.0 server that would work in a similar fashion to (for example) Google's OAuth2.0 flow works.
I don't have an exact answer to this, but let's try to put the pieces together -
i) I am not too sure if you need to save the authorization code in your database for long. This is what Facebook says -
New security restrictions for OAuth authorization codes
We will only allow authorization codes to be exchanged for access tokens once and will require that they be exchanged for an access
token within 10 minutes of their creation. This is in line with the
OAuth 2.0 Spec which from the start has stated that "authorization
codes MUST be short lived and single use". For more information, check
out our Authentication documentation.
See this link, https://developers.facebook.com/roadmap/completed-changes/ (December 5, changes).
ii) What about doing what you are doing till step 1, keep the authorization code and HMAC key in the DB. Let's have the authorization code for 10 mins (or whatever you feel is necessary) and then remove the authorization code.
iii) Let's say you have a single sign-in service that authenticates a client's credentials. When the client app hits the token exchange endpoint (auth code for access token) you'd need to fetch the HMAC key and return the access token. Why not add (some random data + timestamp + customerID/customer name(or something that can be used to uniquely identify the user)) and sign it with the key and return all this data as the access token.
You can think about using a new HMAC key perhaps and replacing the old one.
iv) When the client hits any API endpoint with the token, let the srvice internally call a CustomerIDExtractorService that fetches the HMAC key from the DB and decrypts the access token and returns the customerID to the relevant API. The independent process can then use to the customer ID to fetch data. So basically, I ask you to separate the login/token generation/token info extraction process to a separate unit.
Let's try to map this to how Google could be doing something like this
i) You use an app and sign in to Google Oauth. (Let a black box X from google handle the login).
ii) Your app hits the token exchange endpoint -> The service internally checks if the code is valid. If it is, the service combines some data + customerID and signs it and returns it to the app as an access token.
iii) The app now hits (say) the google+ endpoint. Internally, the service transfers the token to black box X, which decrypts the token and returns customer ID to G+ service. g+ then maps the C_ID to relevant customer data.
Another suggestion
Depending on the scope that the app requested, you can add more info to the access token. Maybe create a JSON object and add/remove fields according to the scope selected by the app. Sign the JSON string as the access token.
Seems your description started off OK, but then I must confess I could only partly follow your approach. AFAIK OAuth2 relies heavily on HTTPS rather than signed requests, although I guess you're free to use such.
I'm not sure about the concept you present to revoke access. Typically this would rely just on the access token (it should expire at some point in time, you could revoke it, and it could be renewed). If for API requests you are pulling keys for a userid then possibly your code is too closely tied to "user" concepts and not OAuth clients (with role, scope, resources)
In any case it's not a simple standard and I guess the discussion could go on quite long and even then I am not sure all could be covered. I trust you've reviewed the RFC at:
https://www.rfc-editor.org/rfc/rfc6749
I see also from your profile you're likely a Java developer. In such case it may be a good idea to review Spring-security-oauth2 at:
https://github.com/SpringSource/spring-security-oauth
If your solution won't use Java a lot of the issues you allude to in your question were approached and solved by such project, so it should give you lots of ideas. If you will use Java then it may help you a lot.
Hope it helps!
Actually most of implementations are using bearer token over https not mac in OAuth 2.0, check this presentation pages 54-56 about why prefer bearer ,on other hand spring implementation is not supporting MAC token for OAuth 2.0 and there is an open issue about it but it is still open
for time-being if you are looking for spring implementation demo you can check this source code but it is using data base to store tokens, and there is connection have to be done between the resource server and Authorization server, in this demo using data base.
one of open source implementation of Spring OAuth 2.0 is UAA of cloudfoundry I attend one session about it also they were telling that there is communication have to be done between both servers. link

Resources