Reputation: 1354
If I save API keys to Flutter_secure_storage, they must be exposed in the first place. How could they be pre-encrypted or saved to secure storage without exposing them initially?
I want to add a slight layer of security where keys are stored securely, only to be exposed when making an API call. But if I have keys hardcoded then they are exposed even if only at initial app run. How do you get around this logic?
Upvotes: 5
Views: 2833
Reputation: 301
What @RobbB said is accurate, but is a little dense for people new to API calls and secret keys.
To clarify, the (non-ideal) route goes something like this:
Ideally, encryption is included:
In both these scenarios the app never has access to the secret key, so the users (and hackers) don't either - at least not easily. Hackers could watch the data stream, find the server, and try to hack the server, but encryption adds a heavy roadblock to that effort. Routes still may exist, but we're getting to the point here that this is probably sufficient security unless you are handling national secrets, people's financial data, health records, or the like.
In most cases a service like Google Cloud Secret Manager or any number of other options are used to handle all the encryption / decryption. They also usually allow locking access to an app signature, setting permissions, and other security features.
Upvotes: 2
Reputation: 1354
I will add some input to this. I am using Parse Back4App which exposes app API keys in the same way that firebase does. I have discovered a few very important security designs which may help with this.
Client side
Don't worry about app API keys being abused. Firebase/Back4App both have some security features in place for this including DoS & DDoS security features.
Move ALL actual API calls to server and call from client via cloud code. If you want to go to the extreme, create a user-device hash code for custom client rate limiting.
Server side
LOCK DOWN ALL CLPs, ALL ACLs, basically lock ALL PERMISSIONS and ONLY allow cloud calls with heavy security checks authorized access to anything server side including outside API calls.
Make API calls from your server only. Better yet, move your API calls outside cloud calls & create "cloudJobs", these run on schedule with Back4App and you can periodically call whatever API from server. Example: a crypto currency app might update prices once per second, once per minute etc. server gets these updates and pushes to clients. No risk of someone getting your crypto API keys and running the limits.
Put in a custom rate-limiting design & design around this so your rate limits would never trip under normal circumstances. If they do trip in excess, ban user & drop their requests.
Also put API keys in .env file on server. Go a step further & use a key encryption hardware service.
It would be a tell-tale sign that your server is compromised if your API keys get abused with this structure.
Want further DoS & DDoS protection? Mirror your server a few times and create a structure whereby client requests can be redirected under attack times or non-DDos/DoS attacking clients receive new app API keys.
... I could go on and on about security & what I've learned but I'll leave it at that.
Upvotes: 1
Reputation: 367
To avoid exposing API key, you should store keys in a '.env' file and use flutter_dotenv package to access it while making API calls. Although this method will not help when making API call. If you really want to secure exposing keys, you should move the API calls to the backend so those network calls cannot be seen by the client.
Upvotes: 2
Reputation: 51
If this is a web project, you could use something like base64 on both ends, then debase and save like this:
SERVER ON PHP
apiKeyEncoded = base64_encode(apiKeyGenerator());
CLIENT:
apiKeyEncoded = await getApiKey();
apiKeyDecoded = base64Decode(apiKeyEncoded).toString(); //this is the usable one, save it.
Now, if the project is focused on mobile use, I don't think you actually need to implement this, tho the code would be the same.
Upvotes: 1