How to secure web api (without login) using asymmetric encryption technique? - cryptography

I have created a Web API (.net core 6.0) that will be consumed by 3 of my clients. Requirement is that each client will have a unique key for decryption. There is no login here. How should I implement this?
This one here (not asymmetric) is key based approach, where key is extracted from the request header and matched with the key in appsettings.json. Is this a safe approach?

Related

Authentication in microservices using jwt

I'm going to build micrservices using Laravel framework.
I have users microservice that processes clients credentials and authenticates them (creates JWT for clients).
Also, there are another microservices that require user authentication.
And the question is, how can i validate clients access tokens in microservices (except users microservice), if the secret access token key is only in users microservice? Or, should i keep the secret key in each microservice?
Instead of handing out the secret key to each service you might want to consider signing JWTs with private/public key pair using RSA. That way only one service has the ability to create/modify tokens and the others can only verify them. Public key should be stored in the services or requested from the authentication service in the backend.
More thoughts on SSO in microservices can be found here.

Use JWT to authenticate separate API Microservice

I am developing an app using microservices in NodeJS. I have built an auth api which handles the usual registration login etc and it issues JWT's
How do I use these to protect routes in a separate API microservice written with Express?
Do I need to use JWT with the secret to decrypt the token in the API app?
You could write a library that you import into your other microservices that requires all routes by default to require authentication. This library could have a mechanism to validate JWT's at the microservice level, so you never need to talk to your auth api to see if a JWT is valid or not. See the description and diagram below:
Your auth server will will need to be the single issuer of JWTs to your microservices. So, when a user logs in and successfully authenticates, your auth server will issue a JWT signed with a private key (signing MUST be asymmetric - RS256 is one example) you keep on the auth server only; do not give this private key to other microservices that you wish to validate JWTs inside of. What you can do is derive a public key based on the private key you sign your tokens with and publish that to an endpoint on your auth server that requires no authentication - the public key will be represented in the form of a JWK (see link to spec). Google does something similar here. Then, in each of your microservices, your library will need to devise a way to make a GET request to the public key endpoint on your auth server every X minutes to see if there are any changes and cache the public key in each microservice. By having the public key cached in your microservice, you will be able to validate the requesting JWT inside the service that is being requested.
Then whenever a request comes into one of your microservices, the library you import will examine the requesting JWT, check its validity, and grant access/authorization if the token is valid. The beauty of using a private/public key pair and asymmetric key signing is that you can validate a token based on the public key alone, but not sign it. So as long as each service has the public key from your /cert endpoint, they can validate a token without ever needing to talk to the auth server or knowing the private key.
This will require a little more work up front, but will yield you massive amount of ease, flexibility, and peace of mind in the future knowing only one source knows your private key.
One common pattern here would be to use an API gateway as the entry point to your entire microservice architecture. Incoming requests for authentication would be routed to the appropriate microservice. If the credentials provided be correct, a new JWT would be returned to the gateway, which would then forward to the caller. For the actual microservice APIs which comprise your application, the gateway would check that the incoming JWT be valid before allowing the request to hit the microservice.
This answer leaves out a few things, for simplicity. For instance, often you would want to have an authorization microservice, which decides what a user is allowed to do. Also, implementing JWT can be involved. You might need a cache layer to keep track of whitelisted and/or blacklisted JWT.
Here is the solution I came up with, to handle user data we can implement an Identity Provider Service (IDP) which is responsible for signing JWTs with symmetrical keys (rs256) and storing user information. The Identity Provider also has an open endpoint which will expose the public key in the form of a JWK (JSON Web Key) which is used to sign the JWT, This endpoint can be used to validate issued keys by any other service (ideally the external service would cache the JWK to reduce traffic to the IDP).
But This also poses another issue, that is we will have to implement more code to validate the tokens with the JWK endpoint. This is where an API Gateway comes in, The API gateway sits between the frontend client and the API server acting as a checkpoint. The API Gateway caches the JWK using the IDP endpoint and validates all the incoming requests. This means we would only have to implement features like JWK validation, rate-limiting, and SSL only to the API Gateway and we will not have to rely on the internal services for implementing these. Plus another improvement to the API Gateway would be to write the decoded JWT data onto the headers so the API Gateway can pass the decoded data for example: x-jwt-email: person#email.com directly to the internal services.
I found inspiration for this implementation from various sources and this was one of the first system designs that have completed building so let me know if there are any loopholes or improvements that could be implemented.
The code for the above implementation can be found here:
Identity Provider
API Gateway

Is API key a way of Authorization or Authentication?

I am using API keys with my web service. I share a key with the client and they send it with every request.
Is this Authorization or Authentication?
An API key is a method of authentication. Using them for security purposes is often frowned upon. You can read more about them here

What is the Signing Credential in IdentityServer4?

We are in the process of implementing Identity Server 4 with our .NET Core web app.
I went trough the Identity Server documentation. When configuring the Identity server (using DI) there is the line:
.AddTemporarySigningCredential
I'm trying to understand what this Signing credential is but couldn't figure out. Therefore I don't know if it's ok to use the built in temporary, or if I should provide a different one.
My question is, what is a signing credential and how should I use it?
In the Identity server documentation this is the definition:
Adds a signing key service that provides the specified key material to
the various token creation/validation services. You can pass in either
an X509Certificate2, a SigningCredential or a reference to a
certificate from the certificate store.
So it seems important :)
The Authorization Server will sign tokens with a key. Resource Server(s) should verify that the token's integrity with a key. Together they form a (usually asymmetric, e.g. public/private) key (pair). By default IdentityServer will publish the public key for verifying tokens via the /.well-known/openid-configuration endpoint.
For development scenarios, you typically want to skip the fuss of properly managing secrets like said keys (which is really important to do properly in production!). For these development scenarios you have the option of using adhoc solutions like AddTemporarySigningCredential, which was used for .NET Core 1.x.
With .NET Core 2.x this will change and you will need the AddDeveloperSigningCredential() extension method.
That answers the question of what it is. On how to use it: you simply call the method you need depending on your .NET Core version inside the ConfigureServices(...) method of your application's Startup class.
Apart from that you don't need to do anything special, except of course take care that you use a proper key pair in production.
See also the docs on Cryptography, Keys and HTTPS and the bit on Configuring Services for Keys. From the latter document, here's a relevant alternative for production cases:
AddSigningCredential
Adds a signing key service that provides the specified key material to the various token creation/validation services. You can pass in either an X509Certificate2, a SigningCredential or a reference to a certificate from the certificate store.

Storing API keys in the cloud for an iOS app

I am trying to find a way to store API keys for 3rd party services in the cloud (for example say I want to connect to twitter, i would need api key and secret to make oauth requests)
I specifically am looking for a way to store it in the cloud and somehow making use of it on demand (I don't want to embed it in the app itself). I don't want the api key and secret to be easily accessible but still want users to be able to make 3rd party api requests.
I'm not a security expert so just off the top of my head I had the following idea:
Store the api key and secret on my server (For example store twitter api key/secret)
Whenever user wants to make request to the 3rd party service, the iOS app makes a request to my server for the app key/secret pair
When the iOS client receives the key/secret, it starts oauth authentication process using the app key/secret it just received from my server (plus the user credentials)
Is this safe enough as long as I send/receive the key/secret values over https? Or do i need to encrypt them further? And would even that be enough?
I would not recommend you returning client credentials (API key and secret) for a 3rd party service to your client. You cannot keep these things secret on a public client like an iOS app.
A better way is to have your server make the call to the 3rd party API and proxy the results back to your app. That way, the API key and secret can be stored safely on your server and if the 3rd party API ever changes, you only have to update your server code, and not all your iOS apps.