I am designing an Api for a client and trying to keep it very basic. Instead of using an external library for the first iteration, we will be setting up an Api Key and allowing users to hit the endpoint with the key and their user id. The endpoint contains an ability that I want to keep hidden from vulnerable attacks, therefore I am thinking of treating the user id and Api key as a username/password for authentication. The key will be encrypted and stored in the database and when the user sends the headers over they will send the user id and api key over to be verified against. That all leads to the question below:
Is BCrypt too heavy of an encryption to authenticate an api endpoint against?
Related
Background
I'm working on a web service with Python as backend using FastAPI.
As far as I know, for the front end user authentication and authorized requests there is JWT. Following the best practices, the token would expired in 15 minutes and refreshed before that.
However, if I want to expose some RESTful API endpoints (e.g. read/write data to my database) for other developers (e.g. Stripe users would call Stripe's API with some keys), I need to create a permanent API key with some configurable permission, like the personal access token for Github. It seems to me that using JWT is not a good option because it's not ideal to set long expiration time or ask external developers to refresh tokens frequently.
I had hard time finding related resources for designing such as system to manage these API keys, even though many companies provide this kind of service.
I would imagine the solution to be having a table in the database that stores the API keys with some permission levels as columns and links with the user table. However, with this method, each call from the external developers/service has to query the database to validate permission, which may hurt the response time compared to JWT. I'd like to know if this makes sense what are the best practices.
Questions
What is the work flow to generate the API keys for external developers/service to call my API endpoints that need user authentication?
How to revoke given API keys?
How to configure/validate API keys for different permissions?
How to design the table to manage API keys?
You should have a secured Web page for developers to generate API keys themselves. So, they can create, revoke, or delete API keys from this page.
Designing your API key table:
key
scopes (permissions)
expires (date)
revoked (boolean)
created (datetime)
modified (datetime)
userId
You can learn more on this article:
https://www.freecodecamp.org/news/best-practices-for-building-api-keys-97c26eabfea9/
Authentication process:
Authentication to the API is performed via HTTP Basic Auth. Provide your API key as the basic auth username value. You do not need to provide a password.
Example from Stripe:
curl https://api.stripe.com/v1/charges \
-u sk_test_dsadsaDSds123DSA:
On your backend, fetch username (API key) from Header and find the API key from the table. Retrieve user details of this API key and do authentication.
I'm working on an API where a user of my API can sign up for my API to get an API key. When I generate this API key, I'm using asymmetric encryption to create a hash that I store in my database.
My question I have is this, once the user generates an API key and then signs out, the next time they sign in, I don't have the API key anymore to display in my app's dashboard. Is this normal / acceptable?
Do other APIs do it differently? i.e. do they offer the API key to the user? and if so, are they storing the unhashed API key in the DB? Is this a balance between user experience and security?
In OAuth2, it's pretty common for systems to show the OAuth2 client id at all times, but the OAuth2 secret exactly once.
If you want to make the user experience good, focus on making it easy to roll a fresh API key without expiring old ones. You can show a list of API keys (not the secret), and when they are last used so it's also easy to let the user disable keys that are likely out of use.
API Keys are not usually considered secure. Typically API Keys are visible to the clients. API keys should not be used to perform secure authorization. However, you can design any system as you want and in your current design if a third-party or attacker can make successful invocations to your API by obtaining the so called "API Key", it's better to hide it and let the user take the responsibility to securely store the key in somewhere else. Also you should make sure in your API, there must be a way to
Revoke an existing API key.
Generate a new API key with an expiry date.
I am planning to secure my rest API in django with a ACCESS_TOKEN.
When ever user is logged in using their username and password, once they are authenticated, I generate a ACCESS_TOKEN and passed to frontend be it Website or Native application. and then later used that ACCESS_TOKEN for further communication.
I am generating this token based on some user data and then encrypting this with public key. Later when application send this for in any request, I decrypt the ACCESS_TOKEN with private key and extract user data data and process the request. This is something similar to session where session data is in encrypted form in ACCESS_TOKEN and only private key and decrypt the ACCESS_TOKEN. This is what I am planning to do.
Please suggest me for following questions:-
1. Is is the best way to secure my REST API? I want to use my API in same way from Web-application(AJAX calling) and NATIVE application(Android/IOS etc) ?
2. What is the best way to expire the token? Do I need to keep track of access token at my end in order to expire them?
Also I do want to use the Oauth in my API.
Most people I see use JWT's that are signed but not encrypted so they store non-PI data like user_id or session_id. I guess you could encrypt it if needing to store personal information but I don't see any other reason. Assuming you are using HTTPS, then only the end client would have access to the information. Sounds like asking for trouble if the secret gets leaked so you would want a really good key rotation scheme since you may not even know its leaked until too late.
Many people using JWTs do so because they don't want a centralized auth server, thus the token is short lived like a few hours or days. If you need really tight control on expiring tokens, you can take a blacklist approach where a blacklist of JTI's (JWT Ids) are stored in a K/V to be checked against. https://www.moesif.com/blog/technical/restful-apis/Authorization-on-RESTful-APIs/
Please someone explain me how to use an api key and what is it good for.
I have searched a lot about this and I got different and conflicting answers. One says that an API key is kept secret and its never sent as the part of the communication, while others send it to the client without any encryption. What is the client's signature? How can he generate it and what can do the server with it? Why should monkeying with api keys instead of using the good old username-password pair? Could someone explain me how the communications look between a client (Android device) and the server (php api) in detail.
I'd appreciate any good tutorials, code samples, and explanations for beginners.
The topic of API authentication is a complex one. Below I'm going to do my best to explain one part of the issue: why is an API key better than a username / password?
Here we go.
When building (or working with an API), a common question developer's ask is "Why does this service require an API key instead of my username and password?" It's a great question!
First, let's talk about what API keys typically are.
API keys are usually randomly generated strings of letters and numbers. Furthermore, an API key typically comes in two parts: an ID and a secret. If you're using a web service like Stormpath, for instance, you might have two API keys that look like this:
API_KEY_ID=kzjbOg3iOm4k4MRpBss76yxlZSPJtoOPaqxirsfX
API_KEY_SECRET=A8FnQWM7RpgGjU3sZjOUgMIq5t8mvAhQES9iE30S
You can think of an API key ID as a username. This is a globally unique identifier which allows the API service to find your account.
You can think of an API key secret as a password. This is a password that, when matched up with the correct API key ID, will grant you access to the API service in question.
The main reason you WOULDN'T want to use a username and password to authenticate against an API is that:
Even if the API is served over SSL, there are many exploits available which can compromise your credentials. If you used your username / password to log into API services, and an attacker grabs these credentials, they have access to your account as a whole.
If you use your username / password to authentication against an API, what happens if one of your servers / API clients is compromised? This means you need to reset your username / password and update it for all of the clients which are using it. This can be time consuming, and costly.
By using a username / password, you're usually restricting yourself to a certain type of API usage. By having API key pairs, you're able to separate out API credentials to different levels of access (maybe on key pair can only access certain data, while another can access other types of data).
API key pairs are, in general, a much better idea. In addition to the obvious security benefits, they also serve other purposes:
If an API key pair is leaked, you can usually create / cycle API key pairs without needing to update every single client you own.
You can use API key pairs to provide sub-account functionality for your API.
Hope that helps!
have a look at this
REST authentication and exposing the API key
Why do some API providers require an API key?
And study a lil about Oauth
I need some advices on how to secure my application:
I have a REST service, using Spring MVC 3
I have my client application, using Ext GWT 2.2
Users credentials are available on the server side only.
SSL available
REST services should only be used by authentificated users.
I have read about HTTP Digest , token based authorization, oAuth etc, but I need some clarification and advices on how to secure my application, and which methods are the best in my case.
here is the methodology we created for our applications, works very well, and is very secure.
this is a very conceptual explanation, there is a lot of code that backs this up, FYI
When user authenticates or creates account, the server returns an x.509 certificate, base64 encoded, that is unique to for the user. The server stores a copy.
Everytime the client needs to access the REST API, client creates a JSON string comprised of the following.
The Users Unique ID (UserID)
A GUID or UUID, that guarantees this call is unique,(CallID) (protects against replay attacks)
A Dictionary (collection of Key/Value) of each parameter of the rest call
we then encrypt that string with the x.509 public key, and encode it back to base64 string, and take this encrypted value and add the UserID to a json object we call the token.
we then put the token into header of each call, and call it something like: X-Auth-UserToken
On every call the server takes the token, looks up the users certificate based on the userID, then verifies that the encrypted part of the token can be decrypted with the private key that the server holds for the user.
once decrypted, the server takes the CallID and verifies that it is unique, against its own calllog db.
if it checks out, the user is authenticated.
once the user is authenticated, you can apply your own authorization rules based on the users uniqueID.
of course, all the above is over SSL.
let me know if you need me to drill down on any parts.