Why does OidcClient not support validating a jwt signed using symmetric key /client secret - jwt

Although Thinktecture.IdentityServer supports signing a jwt using a symmetric key, the OidcClient class does not support validating a token using one - it only supports validating tokens signed using a certificate.
Is this deliberate and are there problems or any limitations with signing a jwt with the client secret?
I am getting some push back with requiring client apps to have a certificate and if I can avoid it without compromising security I would like to do so.

IIRC OidcClient is quite old - we just did not implement it. And you apps don't need a certificate, they just need to be able to verify a signature using asymmetric crypto.
Using a symmetric key makes only sense for server-based apps since that key must be stored securely (otherwise anyone who reverse engineers the app can create valid identity tokens).
The other option is to send the id token back to idsrv to validation (for clients that don't have the required crypto libraries). This endpoint does not exist currently in beta 1 - but is on our todo list.

Related

Is there an online service that can be used to programmatically verify a RS256 signed OAuth2 JWT?

I'm receiving a JWT from Microsoft Azure, and I need to verify it on my server. The JWT is signed using RS256, i.e. using asymmetrical private/public key encryption.
I know that various libraries exist that can be used to verify a JWT signature directly from our backend server. But I'm curious if it wouldn't be possible to verify the JWT signature using an online service? Since it's using RS256 and not HS256, only public keys are involved in the verification process, no private keys or other secrets.
It seems like it would be simple to put up a REST service that can take an asymmetrically signed JWT, verify the signature and give back true/false. But when Googling I can't find any such services. Not even from big names in the JWT-world, like Auth0.
Why is that? Is there some security concern with letting another server verify the JWT signature?

Flutter Security

I am creating a Flutter app which uses Node Js server API. For the authorization I decided to use JWT with private/public keys. Communication between Server and mobile client uses HTTPS. Flutter app stores the token in a keychain (ios) or a keystore (android). My question is related to the need of the additional security measures implementations. I am wondering if the following points are required:
Verification of the server responses with public key by checking the token to identify the server
Verification of the client requests with the private key on the server side (client signs the token with public key)
Are these really needed in order to avoid man in the middle attacs? My objection is related to the performance related to signing/verifying tokens for each communication.
Thank you
I've used JWT our mobile apps for security and these apps had taken the security test(3.party company). The company says: secret your stored token or any keys.
And we know doesn't enough just JWT security. We wrote a custom encrypted algorithm to hide JWT (like sha-1) so we encrypt JWT to this.( you must write encryption code client-side & backend side)
Normal jwt : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
After encriypt: xxs{4=-23dasdxe3 (example)
We passed the security rules with this solution.

What advantage does signing a JWT with RSA have over SHA in the contect of a RESTful API?

I have a backend which exposes a RESTful API which is currently 'free for all' (but uses https).
I now want to add RBAC (role-based access control) and JWT seems the way to go and I read a lot about JWT, but don't see the advantage of using RSA over SHA to sign the token.
Assumption is that the user has authenticated and obtained a key, be it shared or public/private.
Now, it seems to me that in both cases - SHA or RSA HMAC - both parties (client and server) must have the shared key, or their half of the private/public key in the case of RSA. And the server must find that key (in a table or database) based on a claim in the JWT in order to verify the token's signature. Once it has confirmed the purported user in the JWT it will then authorise the request using the configured roles.
So what are the advantages of RSA in that scenario ?
I assume you're talking about RSxxx (e.g. RSA256) and HSxxx (e.g. HS256 (HMAC-SHA256)) algorithms here. The main difference is that HS256 is an symmetric algorithm while RS256 is an asymmetric algorithm. Symmetric algorithms just use one key (or secret) for signing and verifying, whereas asymmetric algorithms use the private key to sign and the public key to verify the token.
If you share the secret used for HS256, everyone knowing the secret could issue or modify and re-sign a token. That would defeat the purpose of the signature if you share the secret with the client. In case of RS256 or any other asymmetric algorithm, only the authentication server knows the private key and anyone who need to verify the token can use the public key to do so. The matching key is usually identified by the KID (Key Id) claim in the header of the token.
But usually, signing and verifying is only done on server side, the client does not need to verify the token and thus does not need to know the key or secret at all. Therefore you can in case of a simple service, when authentication and resource server are the same, still rely on a symmetric algorithms. But once you have one separate authentication server for several resource servers, asymmetric algotrithms should be used.
Thanks for the response, that does help make it clearer.
So basically, for a simple RESTful API, there is no real advantage using RSA over HSA.
Some points that may help others about token-based authentication:
Preamble: the following are all in the context of using SSL.
Firstly, a token is a substitute for username/password credentials: if a client has a token, it is equivalent to having username/password. It took me a while to figure that out. A bit like using a badge at a corporate printer: instead of entering username and password you just place your badge (the token) on the printer and it knows who you are and prints your document.
However, tokens make using an API much simpler because
the client simply adds its token to the http header,
the server only verifies the token,
neither have to deal with authentication flows involving username/pw and managing session cookies.
But the downsides are that
losing the token is like losing the username/password, and
in a complex system involving many components, tokens would have to be shared across all involved backend servers.
Secondly, the client doesn't strictly need to verify the token - it only needs the token - if someone gives you a key to their house or car, you don't typically check the key, you trust the person (maybe sometimes foolishly so) and use it. So a simple random string can serve as a token; the server maintains a simple table correlating tokens to users, no keys involved at all. If a client sends a token that the server doesn't have --> access denied. If it has a matching token --> look up the user that correlates to the token (typically followed by authorisation).
Thirdly, the server typically generates a token either based on trusting the client, or after the client has somehow authenticated, e.g . oauth. Afterwards, the client just sends the token with every request and the server looks it up in its table. However, such server-side tables for random-string tokens may become large and have to be persistent, so either a database or a file is required, and they are typically comparably slow, require maintenance etc, so enter using cryptographic signatures and jwt:
Fourthly, tokens with signature:
the server signs the token and sends it to the client - but the server does not have to store it, also no session cookies as described above
the client stores the token securely and sends it with every subsequent request (just like with a random string token)
the server receives the request, calculates the signature of the jwt, and compares it with the signature of the token sent by the client. Note that there is no file or DB lookup, only computing the signature again and comparing it with the signature sent by the client. If the signatures match then the token must be the same as the one the server issued and hence the jwt header and payload are also the same as issued by the server
the server now interprets the payload, esp. the user (and typically performs authorisation)
So, using jwt means the server does NOT need
a database or file with user names and tokens
to save tokens
to maintain session cookies
It only needs to create and compare a signature. And for that it needs a cryptographic key. This can be a symmetric key for a simple API or an asymmetric key for more complex systems where public keys must be shared.
Hope this helps some other tortured souls who grappled with this topic.

How can I configure Keycloak to use HMAC algorithm as default instead of RSA?

I have created a new realm in Keycloak and in the admin tab Keys -> Active I can see three entries: RSA, HMAC, AES.
Whenever a JWT token is generated the signature algorithm used is RSA. How can I use HMAC instead?
I had the same question and found the following answers:
The latest documentation says that only rsa is supported for access tokens.
(http://www.keycloak.org/docs/3.3/server_admin/topics/realms/keys.html)
There is the plan to sign refresh tokens with hmac. Look at this user mailing list entry for more details:
"It is not great to sign accessTokens and idTokens by HMAC anyway since the
applications will need to have access to realm signing key. As it is
symmetric stuff. This can be security hole as then the application can
generate and sign tokens by itself. Hence we rather rely on the
asymetric cryptography - Keycloak signs tokens with private key and
application has just public key to verify signatures."
http://lists.jboss.org/pipermail/keycloak-user/2017-May/010809.html
Here is the JIRA for it:
https://issues.jboss.org/browse/KEYCLOAK-4623 and internally
https://issues.jboss.org/browse/KEYCLOAK-4622
In Keycloak 20.0.3 you need to go to "Tokens" tab and choose HS256 algorithm:

How can JWT be verified outside the authorization server

Recently, I'm trying to implement an OAuth2.0 server using JSON Web Token (JWT) as access token. I'm very confused about the self-contained feature of JWT. I notice that JWT can be verified anywhere, not mandatorily in authorization server because it is self-contained. How does this feature work? What claims should be included in JWT in order to realize self-contained feature?
Another question is that, if JWT is stateless, it means the server should not store the JWT. Then how is the JWT verified? Can't it be easily forged?
I'm the rookie in this field, I wish someone could help me out:)
JWT contains claims that can be signed, encrypted or both.
These operations are performed using cryptographic keys. Keys can be symmetric (e.g. octet keys) are Asymmetric (e.g. private/public key pairs such as RSA or EC keys).
When you want to verify a JWT (i.e. a JWS), you have to perform the following steps:
Check the header (algorithm is supported, critical claims are in the payload and their value are understood).
Check the claims (especially exp, iat, nbf, aud).
Check the signature.
To check the signature, you need the key and, depending on the algorithm, this key can be
The symmetric key
The public key if asymmetric
When you want to allow third party applications to verify your JWT, you will use asymmetric keys and share the public key with the third parties.
As public keys cannot be used to sign, third parties cannot forge a valid token with custom claims.
The way you share the keys is up to you. The common way is to provide an URL where applications will retrieve them (e.g. Google keys at https://www.googleapis.com/oauth2/v3/certs).