Is there a way to store a secret key (e.g. API key) in flutter?
Use-case:
When registering a new user on my app I need to talk to my backend. Since I only want devices that I know to register users, this backend has only authenticated endpoints. Which means I need to have an API key to authorize the app.
I know you can store environment variables or configurations inside config file or user secrets in a encrypted database but there are a some problems with that in this case:
config file can be recovered with all of its content by just unzipping the apk file which means there are no real secrets there...
To have a secret in a database, you need to put it there first which is not possible before runtime.
I'll probably use environnement variable, and also, I'll obfuscate my Dart code.
There is multiple tutorials, but i'll send you the one from the documentation:
https://flutter.dev/docs/deployment/obfuscate
Related
I'm using Azure as cloud storage, i'm able to upload and download the images/files in Azure blob container using following link.
Azure Blob storage
Now to provide security we are planing to use key vault. Using key vault keys need to access the blob storage in azure.
There is no information available for android to use key vault. If anyone knows anything please post it.If i miss anything to mention please comment i will update it. I'm new to azure implementation.
Edit:- My goal is to display images in app which are stored in Azure blob storage.Instead of accessing azure storage directly by using Key vault i want to access it. After getting secrete key from key vault how to connect azure with that key ?
keys are stored in key vault i want access them and use them to access blob storage
Don't use Azure Keyvault when you're building a mobile app. At least not directly.
You see, we want to keep all app secrets off the device if possible. Even if they're never being stored and will only be in memory transiently.
To solve this particular conumdrum, we're still going to take advantage of Keyvault and all it has to offer and put the Azure Storage API key in there.
But instead of having the mobile app directly access the Table storage, we're going to have an Azure Function do that.
For more details, you could refer to this article.
A small bit of anatomy, in case you're not very familiar with azure cloud: we have Azure Function -> block of executable code, triggered by a http request or other (e.g. database triggers) and Azure Function App which is an umbrella for having multiple functions.
Azure Functions have different levels of security: anonymous, function and host keys https://learn.microsoft.com/en-us/azure/azure-functions/security-concepts?tabs=v4
By creating an Azure Function App, you can secure the function app itself with the OAuth2 protocol https://learn.microsoft.com/en-us/azure/app-service/overview-authentication-authorization
if you're using other cloud providers, like gcp you can also authenticate with a federated token, see https://learn.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation-create-trust-gcp?tabs=azure-cli%2Ctypescript
Because you created this authentication flow, even if your function doesn't have a key (your function security is anonymous), the function app (which you need to authenticate to with OAuth2 flow) can now call the unprotected function URI.
One more note, to actually grasp this, try creating a FunctionApp yourself, where you disable authentification, and if you access the link, you'll see no credentials requirement and check if by copying your AzureFunction uri that you can call the function (anonymous level security).
Now add authentification on FunctionApp and see for yourself that you can no longer call the AzureFunction.
To sum up https://codemilltech.com/mobile-apps-azure-keyvault-dont-do-it/
Now you no longer have to manage secrets, or api codes in your app. All your api's codes and secret now reside where they should - your backend.
Sorry for the wrong answer, I know it might be a bit redundant but this is how I understood the entire access of an Azure Resource(keyvault) through an Azure function which is under the umbrella of Function App, which counterintuitively has the security level to anonymous.
I have read about Parse server which was created by facebook , but I think there are serious security issues.
I can decompile other people apk and get Parse master key, appId and then I can connect this people parse server from my own application and can do whatever I want to do with his data which very dangerous
Even I can make while(true)loop and insert infinite data to the parse server.
So how can I connect any API in Android Studio securily?
You shouldn't put the master key anywhere publicly available. If it's in your APK, you're doing something dangerously wrong. Master key should only be an environment variable on your server.
Sure, you could get anybody's app id and client key (if they added one) by decompiling, but that's the same with basically any API. You need to use the security tools provided by Parse, namely CLPs and ACLs. You shouldn't have any data too sensitive on your server at all. I.e., you never need to store a user's actual payment information, you should use a payment API, pass any information needed to them directly from clients, and store the tokens they give you. I.e. with Stripe, there is a "public key" that is used on the client to talk to their secure server, pass credit card info, and create a card token, and you pass that card token back to your server, which can use the secret key, which should absolutely never be put in a client app, to create charges and things.
CLPs and ACLs restrict access to your objects. CLP (Class Level Permissions) are used to restrict entire tables. They have a cool thing called Pointer Permissions, so if an object has pointers to a user, you can set it to the user set on that field can access their objects. You can restrict public access so you can only get an object with the id, but not find it in a query. You can completely restrict read access, and you should restrict write access on most classes. Business logic goes on the server, you can verify a session token to make sure a user should be accessing an object and then use your master key to actually do necessary updates.
Parse-Server has all of the security implementation you need to protect your user's data. You just have to implement it properly. If you don't use CLPs and ACLs, anyone can decompile your app and get your entire database.
Also, Parse wasn't created by Facebook. It was acquired, then shut down and open sourced about a year or so later.
The Application ID is not a security mechanism and you must not ever use the master key in public applications as it allows you to bypass all of your app’s security mechanisms. It's a big mistake to store master key in the app.
Security must be provided to Parse Server by Class Level Permissions and ACLs (and all connections should be made with HTTPS and SSL).
In my experience, Class Level Permissions should rarely grant Public access (default behavior when creating a Class in Parse Dashboard). I only use Master key for testing purposes and to do some queries/savings in afterSave triggers and cloud functions.
I recommend reading the Parse's Security Guide to understand a bit better how to build a secure Parse API. Here is an important fragment that backups my answer:
The master key, on the other hand, is definitely a security mechanism. Using the master key allows you to bypass all of your app’s security mechanisms, such as class-level permissions and ACLs. Having the master key is like having root access to your app’s servers, and you should guard your master key with the same zeal with which you would guard your production machines’ root password.
You can store your API keys, Secret keys or any other important key information in .C file.
For that you have to use NDK.
You can follow this link for how to use the NDK to secure your file. You can also find GitHub demo app link at the bottom of the page.
Note: If you are using NDK it will increase your APK size.
I have an Android application that sends info to a server, but needs each user to have an assigned API key that they use. The apk build is, therefore, universal, but I need to attach a unique config file to the download containing the API key.
SharedPreferences (or SecurePreferences) is ok for writing and reading from the app on the device, but not for sending down a pre-configured file?
*.properties needs to be compiled with the app?
AndroidManifest.xml meta-data, this is just used at build time?
What's the best way to have the unique API Key downloaded, have it stored somewhere private to the app, and accessible to the app?
What's the best way to have the unique API Key downloaded, have it stored somewhere private to the app, and accessible to the app?
You should get API key specific to user/app on successful authentication or login, then after you can store retrieved key in your SharedPreference of the application.
Set SharedPreferences mode as private mode so other application can not read/write it.
I have been using AWS (Amazon Web services) and in particular simpleDB for a couple of smartphone apps using their iOS/android client libraries.
So far, the data was very benign so I didn't worry too much about data protection.
My next app project will require a "users" table/domain containing usernames and passwords.
What I'm worried about is that someone reverse-engineer the Android java version of the app, then it will be easy to get all the simpleDB data, including all the passwords.
the basic TVM thing (Token Vending Machine, where a temporary token replaces the AWS credentials which are not in the code) doesn't seem to protect against that scenario so it would be great to hear what people think is the recommended approach to do the login part of the app using AWS without being completely unsafe.
Having the passwords table stored somewhere else/accessed in a different way?
Any comment appreciated, Many Thanks.
I can suggest you two approaches to keep your app protected -
1st Approach :
You can keep your AWS secret key into a file with in your app that will be encrypted using private key. On start-up, your code will read that file using public key and can only get your AWS secret key. Please remember following points in this approach -
Your code must be obfuscated.
Your secret key must be in encrypted form into the file so you will get double protection.
Your file must be digitally signed.
2nd Approach :
You can also create your own web site that will manage your user authentications and if user is successfully authenticated it will send AWS Secret key after encrypted it with private key, in his response to the app and your app will use that AWS Secret key after decrypting it with public key. Please remember following points in this approach -
1. Your response must be returned in encrypted form.
2. You site must be secure and must run on HTTPS.
3. Your code must be obfuscated.
I have to store the private key of my app in a secure location in the android device, i read about certStore, but it doesnt allow to store a file in it.
Is there any location where I can store it securely and doesn't get deleted if app re-installs.
You can store the key in the Preferences of your App. This will protect the key from
getting read by other applications because of the underlying file system restrictions of
the Android system.
But this won't protect the key from being read by the user itself.
and if you want to use this shared preference after your application removed and again installed in device then try for Android Backup Manager.
I think its help you in re-installation of your activity's data.
EDIT: Android (unfortunately) does not provide a way to do so. The approach I've used
before is to encrypt this token with another key generated within the app.
Your app key can be algorithmically generated. This, however, is only as secure as
your algorithm. Once that is known this is equivalent to storing the token in plain text.
Thanks.