Xamarin KeyStore PasswordProtection field - java

I'm utilising the JAVA KeyStore class to store my users OAUTH tokens for things like Dropbox.
It's working as it is, but I'm concerned about the security of it as I know very little about how, or where it is stored.
http://www.howtobuildsoftware.com/index.php/how-do/ZPR/c-android-xamarin-monodroid-sqlcipher-correct-way-to-store-encryption-key-for-sqlcipher-database
I am basing my code off of the sample above, one thing that is not provided is why the Password field is null.
So my question is, should this be null? Or should it contain a password that is unique to my application, if the latter, where would I protect my apps password, as I'm in a bit of a chicken and an egg scenario here.
Nick.

one thing that is not provided is why the Password field is null.
The issue in that implementation becomes what "password" should be used.
I'm in a bit of a chicken and an egg scenario here.
If a password was hardcoded within the application you might as well use null (IMHO... but I've worked with security researchers and have seen their toolkits and a hardcoded password supplied to a method call is less than 2 minutes of work for them to crack, so I would imagine a hacker can have it in even less time 😉), same as if the "password" was retrieved dynamically from a Web API over a non-secure channel.
Note: It is not that I am saying using a Null/blank password is OK, I am NOT, continue reading.
Prompting the user to input a password (in the form of a swipe pattern, passphrase, pin, etc..) before each keystore usage would make that implementation way "more secure", but at what cost of app|user usability, only you and your users can that determine that for the app's use-case. Personally I like it when my banking app prompts me for a pin and verifies that access via an SMS and another pin to entry, but that might just only be me. 😂
FYI: Being able to nick' your user's OAUTH tokens for multiple sites via just one app and password would be quite enticing for most hackers and researchers.
It's working as it is, but I'm concerned about the security
And you should be. 😜
That implementation you are referring to, IMHO, is very weak. At a minimum, it should be checking and using Android Keystone provider (AndroidKeyStore) if the app is running on at least API level 18. If your app only supports 18+ (or is running on a 18+ device), you should NOT be maintaining your own keystore file (again IMHO... but I can not imagine a security researcher disagreeing, but would love to hear their argument if they think you should).
Using the keystore provider removes you and your app from creating/maintaining/securing that keystore file as the OS does it and it uses the user's token/password/pin/lock-pattern/etc... to secure the actual filestore itself. No more chicken-egg problem.
Of course this does not cover your app checking for rooted device execution, malicious app installs, current security exploits tests, non-patched and/or missing security patches, etc... but at least it is a start 😎. (I've worked in some really secure devops environments).
Also that implementation is not checking for secure hardware; ie. KeyInfo.IsInsideSecurityHardware, KeyInfo.IsUserAuthenticationRequirementEnforcedBySecureHardware, etc....
Google has some good keystore training material that covers subjects like the keystore provider:
https://developer.android.com/training/articles/keystore#java

Related

Using the Fingerprint Scanning hardware on Android devices to check multiple user's thumbprints against network connected database

I would like to use the built-in Fingerprint scanner on Android devices, or most Android devices, to scan the actual fingerprint image or data into my Android app, then send the fingerprint image or data to an API over the internet backed by a database of fingerprints, to see if a given fingerprint (given on any or most Android devices that have fingerprint scanners) matches someone in the database and returns their name (most basic description of my app that focuses on my main question).
Now, I know how to do the API part over the internet with many different programming languages, I'd probably use NodeJS or Elixir for that part, and I know how to do the algorithm to compare a given fingerprint against a database of fingerprints.
The problem I have is that by default and as per guidelines, the Android operating system and Android devices specifically prohibit accessing the internal fingerprint data, and only allow you to authenticate a single or a few users WITHIN a phone and NOT against an outside database with possibly thousands of users and fingerprints or more, and with the given fingerprint to be checked never having been used on a given Android device before, but simply stored in a database or uploaded from a different Android device to that database (served up as an API over the internet).
Also, getting an Android app to communicate with an API with a database backend is trivial. I don't want to address that either, and I don't want any answers to address that.
Specifically, I'm after a hackish way to get at the underlying fingerprint data/scan/image that the hardware produces, or some fingerprint data that is identifiable to an individual, to send to an API database backend over the internet, and let that backend compare the fingerprint data/scan/image sent to it with the database (and I know how to do the comparison part and all that). However, Google guidelines prohibit accessing the underlying fingerprint data in this way that I need for my App.
Solutions
One proposed solution is to issue every user of my app a USB hardware dongle that fingerprint scans, and use the custom API for this hardware. However, my app's use-case scenario involves random people with random Android phones (that already have built-in fingerprint scanning hardware), potentially thousands of people, and they will have little incentive to buy a USB hardware dongle that fingerprint scans, but if I could make it work, they would surely use my app with their built in Android phone fingerprint scanner.
Another proposed solution is to take an actual picture of a person's, for instance, thumb. I don't know if the resolution would be high enough or if this would be practical enough for fingerprint scanning. So my first actual question is (Question #1:) Can a picture taken with most Android phones, in outside conditions, with flash on, be used for fingerprint comparison purposes against a database of maybe 1,000 users? And return the name of the given random user's fingerprint, which is stored in the database, or return that the user was not found in the database based on their fingerprint, using a picture of their thumb? Even if the answer is yes, this is not the ideal solution.
Another proposed solution is to use a picture of a person's face against a database of around 1,000 users with pictures of their faces, instead of using a fingerprint scanner at all. (Question #2a) Would this be accurate (taking a picture of a persons face and doing facial recognition) for 99%+ of cases, in outdoor conditions with the flash turned on? (Question #2b) If so, can you suggest some open-source software for this purpose to be used on the backend, compatible with say NodeJS or Elixir? Or any other programming language too if necessary... and again, this is not the ideal solution.
The ideal solution, if it would work:
Using Code Introspection in Java to interrogate the Android Fingerprint API to determine its hidden objects, methods, functions, variables, etc, and then using Reflection in Java (google it if you don't know what this is) and hack/steal the underlying fingerprint data/image/scan from the phone, then send THAT to the API with the database backend. (Question #3a) This is my primary question and the one I'm most interested in getting a good answer to. Do you know if this is possible, despite the restrictions built into Androids. (Question#3b) If it isn't possible with all Androids, is it possible with some?
(Question #3c) How would I go about this with Code Introspection and Reflection in Java? Which API and parts of the API should I focus on? I'm aware this is hackish and I'm fine with that.
I am aware of the following
As per Nexus FAQs
Your fingerprint data is stored securely and never leaves your Pixel or Nexus phone. Your fingerprint data isn't shared with Google or any apps on your device. Apps are notified only whether your fingerprint was verified.
which explains very well that you can use fingerprints for verification purpose only. Its just an alternative to any app lock available in marketplace.
and also:
FingeprintManager only has these 3 features:
authenticate : for authenticating user
hasEnrolledFingerprints : Determine if there is at least one fingerprint enrolled.
isHardwareDetected : Determine if fingerprint hardware is present and functional.
you can check FingerPrintManager docs here :
https://developer.android.com/reference/android/hardware/fingerprint/FingerprintManager.html
And I'm also aware:
"and capture the fingerprint data itself" Not possible, since that data simply isn't available. Google's fingerprint HAL implementation guidelines states that "Raw fingerprint data or derivatives (e.g. templates) must never be accessible from outside the sensor driver or TEE".
However, I have read it suggested that:
you can use android.hardware.fingerprint.Fingerprint.class
/**
* Container for fingerprint metadata.
* #hide
*/
public final class Fingerprint implements Parcelable {
private CharSequence mName;
private int mGroupId;
private int mFingerId;
private long mDeviceId; // physical device this is associated with
...
}
to compare against with enrolled one together with FingerprintManager inner class but visibility of api is hidden and you need use Java Reflection
/**
* Container for callback data from {#link FingerprintManager#authenticate(CryptoObject,
* CancellationSignal, int, AuthenticationCallback, Handler)}.
*/
public static class AuthenticationResult {
private Fingerprint mFingerprint;
...
}
This is suggested as an answer on the post: Fingerprint authetication of multiple users
But further information is needed to verify that this actually works in practice on all Android devices or at least some, and could work in my use case with a database backend.
Summary
I can have the users that are in the database scanned in / fingerprints registered, the first time with any method, I just need to know how to use an standard Android phone without a custom 3rd party USB fingerprint scanning dongle to scan fingerprints and send them to this database (and I already know how to send them to the database and compare them, I just don't know exactly how to get them from the Android device so I want to try a hackish-method of Code Introspection and Reflection.)
It may help to review the Android Open Source Project documentation on the Fingerprint HAL. In the Implementation Details section you'll see that no biometric information is to leave the trusted environment.
As discussed in the comments, while the use case may be be admirable, the desire to get Personally Identifiable Information (PII) such as the actual fingerprint image or hash is adversarial to the design of Fingerprint system in Android.
It behoves Google and the Original Device Manufacturers (ODM) to release a patch to remove such leakage, as HTC and Samsung had to do in 2015 as documented in this Ars Technica article about Severe Weakness in Android Handsets Could Leak User Fingerprints.
Ergo any valid answer here would become useless in a relatively short time, reported to bug bounty programs and/or by security researchers.
As pointed out by #halfer, while the application's end use case is benign, the side effects via a reduction in security for users and developers dependent on Android Fingerprint authentication mechanism is not.
Hopefully there is some other path to achieve your goal consistent with Android's architecture.

Is the AndroidKeystore app specific or device specific?

I just want to ask that the AndroidKeystore API used for storing keypair is device specific or app specific. I want to ask if two app using the AndroidKeyStore to store their keypair, then the information for both app will go into same keystore or they will have different keystore containers.
Thanks.
The keystore is app specific. You are allowed to choose the same keystore if you publish two apps, or choose a different keystore. Each has different pros and cons. Some of this is explained in the [signing considerations section here].(https://developer.android.com/studio/publish/app-signing.html#considerations)
If you choose the same keystore for your app it makes various things possible, like code or data sharing through permissions. This is only possible for apps signed with the same key.
On the other hand, suppose in the future you want to sell your app to another company. This can happen to small app developers, where another large game or app development company wants to acquire their app (and they can make a lot of money). If you have signed all your apps with the same key it is very difficult, as the large company needs to be able to sign the app they acquired, so you have to give them your signing key. But this makes it possible for them to produce versions of all your apps, which is not good security practice.
If it was me I would:
choose a different signing key for each app
have my app signing done by Google Play signing, then there are no worries if you lose or compromise your key (or keystore password), or if an annoyed employee takes advantage of your trust to abuse your key.
Keystore API for storage is App specific.
Read this...
Use the KeyChain API when you want system-wide credentials. When an app requests the use of any credential through the KeyChain API, users get to choose, through a system-provided UI, which of the installed credentials an app can access. This allows several apps to use the same set of credentials with user consent.
Use the Android Keystore provider to let an individual app store its own credentials that only the app itself can access. This provides a way for apps to manage credentials that are usable only by itself while providing the same security benefits that the KeyChain API provides for system-wide credentials. This method requires no user interaction to select the credentials.
You can read this on the official site https://developer.android.com/training/articles/keystore#WhichShouldIUse
It is Application Specific not a device specific.
In terms of what you do with it for Android and probably what you're looking for since you mention signing apk's, it is your certificate. You are branding your application with your credentials. You can brand multiple applications with the same key, in fact, it is recommended that you use one certificate to brand multiple applications that you write. It easier to keep track of what applications belong to you.
It is app specific. But you can use same keystore for multiple apps.
Important!!!!!! Keep more copies of key file. If your app is pulished on play store and you missed the keyfile, you never able to provide updates for your app.
You need to build apk with same keystore if your app is already live on playstore otherwise google will not accept your build. You need start again from fresh upload with different package name. App with same package name is also not accepted. You will loose all your app’s rating and download figures as well.

How to verify POST data is sent from Android app with correct SHA1 signature?

Recently my game has been hacked and one user submitted an impossible score to the server. The score was submitted with a verified checksum, and correct data.
I'm convinced that the user must have reverse engineered my APK file to find the POST request.
Now I wonder what would be a good way to prevent this from happening again and I thought about verifying the SHA1 signature of the app. Maybe this way I can make sure that the app is signed by me, and is not a reverse engineered and changed version of the app.
Would this be possible? Or would there be a better solution to solve this?
I am using LibGDX by the way.
First of all, you really have to obfuscate your code. You can find more information about ProGuard and code obfuscation here.
Second of all, you can use GoogleAuthUtil available in Google Play Services, which is available for devices running Android 2.2 or higher.
GoogleAuthUtil does exactly what you need:
Your client server calls go to Google via a HTTPS request, Google checks whether or not the call is made by an app signed with your release certificate, and then it sends the request to your server.
You can find official tutorials about how to implement this here and official documentation here.
Cheers!
1) Use code obfuscation for ex. Proguard. This kind of tools available not only for Java.
But be careful with that - obfuscated code may work slowly or contain additional bugs.
2) Add App Licencing check (this will check app signature with Google Play):
Watch this video with attention:
https://www.youtube.com/watch?v=TnSNCXR9fbY
As I remember he mention technics used at runtime to verify your app not hacked or modified (zip check, etc).
3) Make sure your app/server use secure connection (SSL/TLS) only with MODERN cipher suites. This will mitigate downgrade attacks.
You can use this generator to build config with MODERN cipher suites for your server:
https://mozilla.github.io/server-side-tls/ssl-config-generator/
Also you can use certificate pining on client side - this will mitigate authority attack.
Do not use plain HTTP connection.
4) Use some kind of request signing (like Amazon AWS does)
You can get core idea from their docs.
http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
Also this article should be helpful.
5) Prohibit usage of your app on ROOT'ed devices by adding run time check. Because of on rooted phone it's easier to hack or analyze your app.
6) You can decrease fraud by adding some ban system to your online game - if somebody hack your app and send wrong data to your server => add this user to ban list on server side (by IP or by user ID, etc). Probably add users to this list temporary (ex 24 hr, 7 days)
7) + if you are using Json/XML as data formats for network layer try to use binary format like Protocol Buffers. Binary serialization formats more efficient and hard to reverse engineer.
If you want to verify the signature of your app without the possibility that this is cracked too, you would have to upload the whole apk and make the check on a server. This is not a practicable solution.
The only secure android app is a pure terminal app, which means you'd have to do all computing on a server. Most of the time this won't be possible because of latency.
That's why we Android developers have to live with this: an app is not 100% secure.
But you can get close to it.
You might want to read Security with HTTPS and SSL guide for securing your communication.
Also you'll want to ensure your client is hard to crack: android app piracy prevention and Combating Android App Piracy: Xposed
In your case you'll also want to implement server-side request validation:
If you have a game with a server side, users probably have an account. If a user sends a clearly impossible score, automatically disregard the request and ban the user (and his ip). (But also have in mind that this should never happen to a valid request, otherwise users might get angry and stop playing.)
You can obfuscate your code better and use some very obfuscated secret to sign your requests. With that you can increase security.
But if all your game run in client it can't be completely secure. Because it doesn't matter what you use to sign, if you do it in client it means you have the secret or private key in client and then it can be hacked.
To make it more secure you need to involve some game logic in server and then control in that logic that the user isn't cheating.
Verifying the integrity of your app won't be enough, since the request can be easily faked outside the app or modified in memory on the fly, using a rooted android environment. Even more, you cannot totally avoid it.
This is a problem shared by all applications running in a machine out of your control (all client applications). You can't never trust the data coming from them.
As I can see it, you have several choices:
Obfuscate the code and make the app more difficult to be reverse-engineered. Notice that this do not solve the problem, but minimizes it.
Move processing to the server. The more game-play is controlled by the server, the less vulnerable you app would be to this malicious behavior.
Automatically detect impossible scores and close their accounts
Cheers,

Best Practices for Session Management on an Android Device

In an android application, what are some of the best practices for session management?
In my case, I am using Active Directory to authenticate users. I was thinking of storing a last_authentication_time variable on the phone, and requiring the user to log in after a set amount of time. If the user hasn't passed that time period, skip the log in screen. Otherwise, force the user to log in.
Is there anything wrong with this? It seems pretty simple, I just want to be sure to do this the 'proper', secure way.
Yeah its a simple concept although i don't see the point in it, the user either wants to stay logged in or input the password, why would inactivity force the user to enter a pass?
as for a secure way you can either use some kind of encoding (preferably sha1) to store an encoded version of the password in shared preferences or use the account manager as a more secure way of doing this. its a lot more complicated than shared preferences but its also a lot better, search google on how to add an account in the account manager.
Hope this helps.

Can I create a Google account programmatically?

Does anybody know if via the google api in java
I can create google accounts programmatically.
Yes
(ish)
The Admin SDK Directory API allows you to create accounts which work with Google tools (Gmail, Calendar, etc.) but are not #gmail.com / #googlemail.com accounts.
This is used by companies to automate creation of accounts for online google tools when new users are added to networks and similar scenarios.
User management is documented here.
This replaces the provisioning API which was deprecated in 2013.
NO
The only possible way to do this would be to use a web automation framework. Python is great for web automation using tools such as mechanize. I've never done it in Java, but you should do a google search for java programmatic web browser or java web automation.
On top of that you would have to incorporate an OCR package to beat the captcha.
There is a reason that google, nor anyone else, allows the programmatic creation of accounts. Spammers would have a field day. Within days there would be no valid accounts left for any new users to use. In short, it would be a disaster.
As others have pointed out, you cannot create Google consumer accounts (ie, #gmail accounts) via any sort of API. It would create a field day for Spammers. To make it difficult for Spammers, Google uses tactics such as CAPTCHAs to prevent abuse.
But, you can create Google Apps accounts via their Provisioning APIs. A Google Apps account is basically a white labeled version of Google Apps (Gmail, Calendar, Docs, etc) that is under your own domain name.
For the same Spam concerns, your Google Apps account would have to be either a Premier domain (where you pay for every account you provision) or an Educational institution (I assume some sort of verification process for that). So, since you have to pay for each account, it's not a huge risk for spammers (unless they want to pay big $$$ for each account.. very unlikely).
It depends on your definition of create account...
it is possible to create an account inside a google group, or domain. By using the code below you can create accounts for your google group/domain. For this scenario YES you CAN create a google account.
However, if you want to create a google account as in #gmail.com... I really have not found a way to do it programatically.
Here is the link of where to download the google api, and the Documentation.
https://developers.google.com/google-apps/provisioning/#creating_a_user_account
Good Luck.
import sample.appsforyourdomain.AppsForYourDomainClient;
AppsForYourDomainClient client = new AppsForYourDomainClient(email, password, domain);
client.createUser(String username, String givenName, String familyName, String password)
The real answer is YES.
The fact is that we don't know (yet) how.
The proof is that an account can be created from any android device without any captcha, without a phone number and without an email.
So the secret is inside android codebase.
MAYBE?
I am going to write an answer that has not been written so far, but which could actually break the EULA (if that's the case, can someone point out the specific paragraph of it that prevents this?).
The solution is: redirect Google's CAPTCHA to your user.
Assuming your software has a user, you could present them Google's captcha so the account is created by them, for your system, without them knowing.
Would this work for you?
You can do that theoretically, but Google's account creation - like other services - uses image recognition for confirmation that you're a user (aka CAPTCHA) and you need to be able to write image recognition program that can do that.
AFAIK there's no programmatic API from Google to create accounts, since doing so would open them up to spammers/scammers/etc... which the CAPTCA was meant to prevent.
Why would you do that? I am not sure Google allows that in the first place as far as EULA.
I am going to assume that you aren't telling us your use case which is really to have a convenient way to use google logins on your site (because that's the closest you'll get and be legit). I would check out using OpenID in the same way SO does.
Actually, you can create if by google account you mean your own domain (those business ones using google).
You can check it here
YES...
Actually you can do that. You can write CUrl scripts and can use different APIs available to break the captcha.
Breaking a captcha is key thing here.
The fact that Google's account creation UI requires a CAPTCHA is your first hint that the answer is NO.

Categories

Resources