Fingerprint authentication in Android app wrapping a web page - android

I have a webpage that needs authentication which can be tedious to enter on mobile so I was thinking of creating a wrapper application that could login the user (only one - me) automatically with saved credentials. In order to protect the credentials I want to use the fingerprint API (I use a Samsung S5). However this is new stuff for me so I have few questions about the feasibility:
Is it possible to automatically log into a web page from an app wrapper?
Could this work with a non-trusted certificate (I have to generate my own)
Can I encrypt and use the fingerprint to decrypt the credentials so they are secure on the phone?

Is it possible to automatically log into a web page from an app wrapper?
yes
Could this work with a non-trusted certificate (I have to generate my own)
No in general, if you are meaning HTTPS certificate. but android webview with client certificate may help
Can I encrypt and use the fingerprint to decrypt the credentials so they are secure on the phone?
Yes. in pratice refer to http://android-developers.blogspot.com/2015/10/new-in-android-samples-authenticating.html

Related

Provide private key and certificate for android app

My app needs to consume webservice, and I would like to authenticate app against server with certificate.
However, embedding keystore with signed key into package is considered bad practice (and explicitly warned against: https://developer.android.com/google/play/asi) as it can be extracted an decrypted.
I can generate private key with android provided keystore, and use it - but I still need it to be signed in order to verify it on server side.
In ideal case there shall be certificate chain, with trusted root authority and containing metadata of signed app package I could verify on server side.
Or is it somehow possible to use package signature in certificate generation process to prove that self signed certificate originated form untampered package?
A bad actor ("Trudy") can flash any custom Android ROM, including a ROM that removes package certificate validation during APK installation. Thus, any query that your app makes to its Android host OS is essentially a request to Trudy.
So, it might be possible to uncover the installation of a hacked APK with an unadulterated OS. But with an adulterated OS, all bets are off.
I think any solution for the client to self-validate would necessitate an authoritative validation of the host OS. Not easy.
Is it somehow possible to use package signature in certificate
generation process to prove that self signed certificate originated
form untampered package?
(1) Do you mean that each client generates a different self-signed certificate after installation and somehow cross-references this against the apk package signature in order to authenticate? Then no, this will not stop Trudy. (And it would not be useful in authentication, either.)
(2) Do you mean that the client has a universal private key embedded in the APK and that metadata on the package certificate can be used to verify against the private key? I do not know offhand if there are any available fields in the package certificate metadata in which to add this information. This is an interesting approach that you suggest. However, since Trudy might be the OS, theoretically Trudy could mock any result it wishes. I do not see this stopping Trudy.
This (SO) post by a developer for Proguard offers 5 options for handling secrets in your Android app. He notes:
Intrinsically, nothing on the client-side is unbreakable, but you can
certainly raise the bar.
I understand that you want user authentication of Webservice (API) using user's private key, and signed token would be verified at the server with user's certificate or public key already registered there at the time of user registration.
Are you looking to use external USB Token to store private key securely or you want to store the private key to be stored in Android device memory?
We have worked on such requirements on desktop (sample at https://web.signer.digital/Home) but not on Android. I know we can connect USB Cryptographic Token (like ePass2003 or others) to Android device with OTG USB and drivers for Android for some devices are available to access from Android but didn't worked on it actually. But this can be direction for you to look into.
A mobile application is public app, because an end user could possibly view and modify the app code. So, your application can't keep secrets from malicious users. That includes client certificates, which are required for mutual TLS (mTLS).
It is not safe to store any client certificate on the Android device for machine to machine (don't mix machine to machine with user to machine) mTLS authentication. It can be exported and then used on other devices by any user.
Operation systems (Android as well, some browsers, e.g. Firefox may have own) provides certificate storage, where CA certificates are stored and where client certificates can be stored.
It is a good idea to store user (issued for the user, not for the app/machine) client certificates there. Then mobile app should get an option to select which user client certs should be used for mTLS. But I want to authenticate my application without any user interaction. won't be possible. There must be at least initial user interaction: user client cert import to client storage, mTLS app configuration. That's IMHO the best and secure mTLS implementation. Real world example: Rocket Chat app.
You are asking for reverse TLS based verification ? Usually, clients verify web services because client's host OS trusts a particular CA certificate that is also used to generate the web-service TLS certificates.
The difference is:
web servers are protected and controlled by authors. Client devices are not. So, having a private key in app to sign the data sent to server is futile.
Still, You can explore Google's Licensing implementation with server side verification to enforce that a legitimately installed and licensed app can contact the server.

Does Android have something like the Apple Keychain? [duplicate]

Is there an equivalent to iOS's Keychain on Android?
My understanding of the Preferences API is that it is not encrypted. For my application it doesn't matter whether these credentials are persisted across devices (i.e. a different use-case to iPhone-like Keychain in Android?)
I also looked at the KeyStore API but it seems to leave the actual storage of user credentials up to the application developer.
Short answer, there isn't one. But you can expect the filesystem to be secure.
Each app operates under a different user, and the filesystem used to store app data is secured by normal UNIX user permissions. So each app's file access is sandboxed by default. The filesystem also may be encrypted.
This page from the developer's site explains it better: http://developer.android.com/guide/topics/security/security.html
Actually there is:
By integrating Smart Lock for Passwords into your Android app, you can
automatically sign users in to your app using the credentials they
have saved. Users can save both username-password credentials and
federated identity provider credentials.
Integrate Smart Lock for Passwords into your app by using the
Credentials API to retrieve saved credentials on sign-in. Use
successfully retrieved credentials to sign the user in, or use the
Credentials API to rapidly on-board new users by partially completing
your app's sign in or sign up form. Prompt users after sign-in or
sign-up to store their credentials for future automatic
authentication.
https://developers.google.com/identity/smartlock-passwords/android/
Expanding upon #DJPlayer's answer:
Some relevant articles. The third includes a github app that demonstrates using the keystore provider to generate keys and then encrypt strings.
Android Keystore System
Where is the best place to store a password in your Android app?
How to use the Android Keystore to store passwords and other sensitive information
Also see Android Storage Options for ways to store the encrypted password - my recommendation is Shared Preferences.
Note that according to the second article with root access and a bit of knowledge of how your app uses the keystore (which might be obtainable from decompiling your apk), it's possible to hijack the private key and use it to decrypt encrypted material (ex: the persisted password)
http://developer.android.com/reference/android/security/KeyChain.html
Keychain for OS 4.0

Securing a web service so it can only be called by a specific Android application

We have a web service that should only be called by a specific Android app. What solutions are there for this problem?
The requirement is to not use authentication at all.
If it's only your client and your server, you can (and should) use SSL without purchasing anything. You control the server and the client, so each should only trust one certificate, the one belonging to the other and you don't need CAs for this purpose.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use the keytool included with the Android SDK for this purpose. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android, both server and client side. There is also a complete walk-through in my book, Application Security for the Android Platform, published by O'Reilly.
You'll normally store that certificate/private-key in a keystore of sometype (a KeyStore if you're using Android) and that keystore will be encrypted. That encryption is based on a password, so you'll either need to (1) store that password in your client somewhere, or (2) ask the user for the password when they start your client app. What you need to do depends on your usecase. If (2) is acceptable, then you've protected your credential against reverse engineering since it will be encrypted and the password will not be stored anywhere (but the user will need to type it in everytime). If you do (1), then someone will be able to reverse engineer your client, get the password, get the keystore, decrypt the private key and certificate, and create another client that will be able to connect to the server.
There is nothing you can do to prevent this; you can make reverse engineering your code harder (by obfuscation, etc) but you cannot make it impossible. You need to determine what the risk you are trying to mitigate with these approaches is and how much work is worth doing to mitigate it.
I guess this will work with proper authentification in place. First post I just stumpled upon was this one:
Securing communication from android to a web service
Hope it helps =)
If you're absolutely certain this web service will only need to be accessed by authorized applications/devices, go with client-side SSL certificates and restrict access at the server to only clients with authorized certs. This has the bonus feature of forcing SSL at all times so you don't like auth secrets over an open channel. Here's a quick guide for Apache, but you could use nginx too:
http://it.toolbox.com/blogs/securitymonkey/howto-securing-a-website-with-client-ssl-certificates-11500

Different ways to authenticate smartphone application like Android

I am looking for different ways to authenticate client like android, iphone, windows and blackberry app and which one is better and why
As per my research I know of 2 way to authenticate client
1. Private key embedded inside smartphone app which will be used to sign the message : Problem with this is its easy for hacker to get access to private key
2. Client certificate
Are there other ways to authenticate these smartphone app and which one is most secured?
Both of the options you list here are really the same. A client certificate is really just the public key part of a private/public keypair that is signed by some entity along with some identification information.
The best way to authenticate the client is to use mutually authenticated SSL. You can use self-signed certificates here so you don't need to buy any from a CA, assuming you control all of the clients that you want to allow access and you control the servers they are going to talk to. This will ensure that your clients only receives data from your legitimate server (configure the SSL system for your application to only accept the self-signed certificate that your server is using) and your server only accepts data from your authorized clients (configure your server to only access the self-signed certificates deployed in your app as a resource for client authentication). There is a complete step-by-step rundown on how to do this for Android in Application Security for the Android Platform, published by O'Reilly.
You are correct in that you need to embed some secret information (a private key) in your client application and an attacker will be able to compromise it. The best solution you have within Android right now is to put the certificate and private key in a Keystore that you include in your application APK as a resource and have your application access the Keystore when it needs to use the key. That means your application will need to have the password to the Keystore. So, how you protect that password becomes important. You can obfuscate your code to make it harder for an attacker to determine that password, but that will only slow down a determine attacker who is reverse engineering your application. However, short of requiring the user of the device to type that password in every time they want to use your application, that's the best you can do. If your client app that is running on the device needs access to something that it stores, a person with access to that device will be able to access it as well. All you can do it make it more difficult.

Is there an equivalent to iOS's Keychain for user credentials on Android?

Is there an equivalent to iOS's Keychain on Android?
My understanding of the Preferences API is that it is not encrypted. For my application it doesn't matter whether these credentials are persisted across devices (i.e. a different use-case to iPhone-like Keychain in Android?)
I also looked at the KeyStore API but it seems to leave the actual storage of user credentials up to the application developer.
Short answer, there isn't one. But you can expect the filesystem to be secure.
Each app operates under a different user, and the filesystem used to store app data is secured by normal UNIX user permissions. So each app's file access is sandboxed by default. The filesystem also may be encrypted.
This page from the developer's site explains it better: http://developer.android.com/guide/topics/security/security.html
Actually there is:
By integrating Smart Lock for Passwords into your Android app, you can
automatically sign users in to your app using the credentials they
have saved. Users can save both username-password credentials and
federated identity provider credentials.
Integrate Smart Lock for Passwords into your app by using the
Credentials API to retrieve saved credentials on sign-in. Use
successfully retrieved credentials to sign the user in, or use the
Credentials API to rapidly on-board new users by partially completing
your app's sign in or sign up form. Prompt users after sign-in or
sign-up to store their credentials for future automatic
authentication.
https://developers.google.com/identity/smartlock-passwords/android/
Expanding upon #DJPlayer's answer:
Some relevant articles. The third includes a github app that demonstrates using the keystore provider to generate keys and then encrypt strings.
Android Keystore System
Where is the best place to store a password in your Android app?
How to use the Android Keystore to store passwords and other sensitive information
Also see Android Storage Options for ways to store the encrypted password - my recommendation is Shared Preferences.
Note that according to the second article with root access and a bit of knowledge of how your app uses the keystore (which might be obtainable from decompiling your apk), it's possible to hijack the private key and use it to decrypt encrypted material (ex: the persisted password)
http://developer.android.com/reference/android/security/KeyChain.html
Keychain for OS 4.0

Categories

Resources