When the user enters username and password into an mobile app( iOS ,Android or windows app)it calls a thirds party oAuth login web service which responds back with oAuth access token and refresh token. Now the app generates a JWT and signs with a Secret key stored in the app. This jwt is used for authentication on a set of In house APIs
In this context, is it safe to trust this AUTH model? Since in-general JwT are generated on the server side , so the integrity is maintained.
What are the pitfall of signing a jwt in mobile apps? Will the secret signing key stored in the apps ever gets compromised ?
Will the secret signing key stored in the apps ever get compromised?
Yes, the signing key can get compromised. This can be done by decompiling your app executable.
Instead of storing the token in a sqlite database or local file, you can make use of the secure storage that each of these platforms provide.
For iOS, you can simply use the Keychain, a secure storage intended for this purpose.
As for Android, a similar functionality is provided by the Keystore.
Related
I'm trying to use firebase email authentication and enable biometrics.
The solution I am able to come to is:
enable biometrics and get the fingerprint token
encrypt the user's username+password with this token
store the encrypted username+password in app storage
when user authenticates using biometrics, app decrypts stored username+password and logs in firebase.
The issue is of-course the difficult choice of storing encrypted username+password locally.
Is there any better alternative like
saving an encrypted firebase token instead of username+password?
saving the token in a server?
How do professional apps do it with firebase?
Use Symmetric & Asymmetric keys concept with Android keystore
Follow the Salesforce Mobile SDKs strategy in using the Android Keystore
(more details here:https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/auth_secure_key_storage_android.htm)
To summarize the steps :
The application upon installation and first run creates an asymmetric key pair and a symmetric key
The application stores the asymm. keys in the Android Key Store. Key Store access is granted only when the user unlocks phone (e.g. w/ pin code or biometrics. this step is optional. you can do it without this step)
The application encrypts the symmetric key with the public part of the asymm key pair and stores that in shared preferences
It is the symmetric key that is used to encrypt/decrypt the Firebase token or username + password whichever you want to use
To access the encrypted symmetric key, the app has to first obtain the private key from the Android Key Store, decrypt the symmetric key and then use it.
My flutter app currently uses OAuth to authenticate users. I am using the Resource Owner Password grant. I want to add biometric authentication to the app (finger/face id).
What is the approach when adding biometric authentication to an app which still needs to do OAuth in the background? Do I store the UID and PWD in a secure location and use it int he background to authenticate against OAuth? What is the most secure pattern for this scenario?
you usually store a session token returned from the OAuth system that you check every so often for expiry, you don't save the User/Password with OAuth systems
We have a service where user can sign-up. This process is protected by reCAPTCHA to prevent automatized sign-ups. The problem is that on mobile devices reCAPTCHA is not a convenience. Therefore we decided that the sign-up API will accept also some special tokens instead of reCAPTCHA response.
Now the question is how to implement this token. Our first approach was to equip the mobile application with some constant secret that would be sent to the server as the token. But this secret can be revealed if a hacker redirects the request to his server (by updating DNS record of the API domain and installing his certificate as trusted to the mobile device).
Now our final approach is to compute the token as HMAC-SHA1 on username+secret (do we need a here secred - maybe just for making the input long enough?). The username will be taken from sign-up input. Then the server would authorize it by validating the hash. In his case it would be possible to do a replay attack but it is OK because duplicate username would be rejected.
Is this approach correct? Maybe there are other alternatives to captcha on mobile devices?
Also is it possible to get and reverse engineer the application from iOS (ipa file) considering it will be hosted in Appstore and to extract the key (and secret)?
In case of android this is possible - is there a way to prevent it?
You found the disadvantage: you still with a token which doesn't change for the same user. It's ok in your use case (register), but there could be another use cases where is not useful (for example a password recovery feature. In that case, a possible hacker might generate valid tokens for any user is your are asking for the username).
My solution would be:
Create an algorithm (on both mobile app and your backend) that takes a "public token" and creates a "secret token", which solves the captcha. It might be a simple SHA1 hash (I don't recommend), a combination between public token and a salt, the user id and public token, etc...
Create an endpoint on your API that generates public and secret tokens. Store secret token in your backend and return public token to the client (mobile app).
You app then should ask for the public token, generate the secret token and send it to the API. The API verifies that secret token is already stored in your database, and if it's the case then captcha is solved.
An improvement would be making stored secret tokens to expire after X seconds.
Hope it helps!
We decided to go with Hawk to not to send credentials over the wire. It will be used for iOS where it shouldn't be possible to reverse engineer the app and get the secret key. For Android we'll use some reCAPTCHA library for Android.
What is the best place to store API keys, Database encryption keys etc. in the app code so that nobody can get it by decompiling the code ? I used proguard to obfuscate the code but it didn't work on Strings.
There is no way to store them in the app. The app can be decompiled or executed on a modified device which provides more access to the app's memory, or the app can be modified by the attacker to add additional logging of network or storage/database traffic, etc.
For authenticating to servers, your app should probably obtain auth tokens (or similar) by exchanging user-entered credentials for such auth tokens or by obtaining these auth tokens from AccountManager or similar APIs. You could also use SafetyNet Attest API (https://developer.android.com/training/safetynet/index.html) to attest to your servers that it is your app signed with your signing key which is making the request.
For database encryption, the app could generate a random encryption key on-device, either linked to user-entered credentials or stored in Android Keystore, or simply rely on protections offered by Android to apps. It depends on your threat model (i.e., why do you think you need to encrypt databases?)
On my android application I use the dropbox API. I hardcode the app key and secret. But to authenticate I need to log in using the dropbox account.
But whats the point of using a app key and secret if you have to enter a username and password.
Also what if you would like other people to be able to upload to your dropbox without using the accounts username and password. Can they use the app key and secret to just upload to the account without entering the accounts username/password?
You are a bit confused with what are app key/secret used to do. In briefly, a pair of app key/secret is used to identify an app. Is it a valid app? Is it authorized by user? And is it out of API call limit/throttling? Therefore, only with key/secret, app has no right to access an unauthorized user's private data. I'm sorry but I have to say allowing people upload data to your own cloud is not a good idea. At least, dropbox is not for that purpose. Instead, why not try some other cloud storage service, like Amazon S3?