I am currently developing an api for a website i run. The api will be used in a number of places, and one of those places is an Android app.
It's purpose is to allow users to login, and and download files. I have the api build, and it will be using HTTPS so all of the data is fine when being transferred.
The issue i am having is that the API calls require an API key. With this key you will be able to have access to certain functions of the API that may cause issues.
What i was wondering, is there a way to secure this API key? I am not an Android developer at all, but people will be using the API that are on Android so i need to work out a solution.
Below is an example of the flow that the API uses:
// Log the user in with their username and password (HTTPS, so not really an issue)
romhut.request('/api/users/login?apikey=KEY', {username : 'scott', password : 'password'}, function(r) {
console.log(r);
// Once you have the token, request the API key that allows actions such as downloading
romhut.request('/api/files/download?apikey=KEY', {token : r.token, file : file}, function(d){
console.log(d);
// Download the file
}, 'POST');
}, 'POST');
No. You cannot protect the API Key once you embed it into an Android application. The app needs access to the API Key, so someone with access to the app will be able to recover that key from within the app and use it for their own purposes. The best you can do is to obfuscate your app so that reverse engineering it is more difficult (the goal is to make it more difficult for the attacker to reverse your app than is worth his time). You need to decide how much effort in this regard is called for, based on the risk of an exposed API Key, but you can never make it impossible to recover, just more difficult. In reality, your best bet is most likely to turn on Proguard during your build process (so things are obfuscated to a decent degree in the APK with no work on your end) and hope for the best.
You should create a specific API key for each user. There is no really good way to secure data that is actually in the user's hands (Ask makers of copy protection about this) Then you can use HMAC to hash together the API key and the requested API and verify that the same thing happens on both ends. See: http://en.wikipedia.org/wiki/Hash-based_message_authentication_code (PHP has a function for this.)
In fact it would be more accurate to say that there should be a many-to-one relationship between keys and users since you may have different and/or revoked keys for a user.
For an excellent overview, see: https://security.stackexchange.com/questions/18572/is-it-okay-for-api-secret-to-be-stored-in-plain-text-or-decrypt-able
Is Android keystore a direction to look at? Then, perhaps an encrypted string is posted to the API based on the key that is stored in android key store by the app at the time of installation. That way if there is a succesful decryption, it can serve the requests.
Related
Context: I have two apps, both signed with the same signature. The first app has data stored in internal storage that I would like to migrate to the second app.
Question: How can I access the data in the first app from the second app? The Android documentation makes reference to "signature permissions" (https://developer.android.com/guide/topics/permissions/overview#signature and https://developer.android.com/training/articles/security-tips#StoringData) and hints that it is possible to share data between apps with the same signature, but I cannot find clear guidelines about how to do this.
It seems like it might be possible by creating a content provider? Or is it possible to directly access the files, since I understand from the docs that they will be running with the same user / same process?
Ideally this process can happen with minimal intervention from the user, and can all happen from the second app (e.g. the second app can recognize that the first app is installed, prompt the user to migrate, and then read the data from the first app and move it to the second). It would be even better if it was possible to move the files (rather than copy) because we potentially have a lot of data and the user may not have enough disk space to copy the data.
It seems like it might be possible by creating a content provider?
Yes. You can create a signature-level permission and use that to protect access to any of the standard IPC options in Android, including ContentProvider and Service.
Or is it possible to directly access the files, since I understand from the docs that they will be running with the same user / same process?
No, two apps signed by the same signing key to not run as the same user, let alone in the same process. android:sharedUserId has the apps run as the same user. This was never a great idea, is deprecated, and is likely to go away soon.
It would be even better if it was possible to move the files (rather than copy) because we potentially have a lot of data and the user may not have enough disk space to copy the data.
That suggests that having two apps is a bug, not a feature, from the standpoint of the user. The closest you will be able to do to a "move" operation is "delete-after-copy", so plan your copies to be as granular as possible so you can delete as you go.
Suppose I have an an apk that I want to reverse engineer but there are some small problems regarding this. For instance if the application uses Google siging mechanism to signin into the app then I would not be able to signin after modifying the apk!
There are also couple of other reasons that why not to modify an apk with resigning it with custom keystore...!
Is it possible?
Or is there any other problem to tackle this?
It is not possible1 to modify an APK without invalidating the signature. That is the whole point of the signature.
However, the APK signature and Google's Sign-in service are different things. "Signing" and "sign-in" are different words with different meanings. From a theoretical standpoint (at least) an APK that has been modified should still be able to successfully use Google Sign-in.
Here are some background links on APK digital signatures and how they work:
Wikipedia: Digital signatures
APK Signature Scheme v2
APK Signature Scheme v3
1 - At least not currently. If someone manages to break the "crypto" that is used to implement the signature, then all bets are off. But we are probably OK for a few years ...
I tried looking up what an Android key hash on Google.
But all I got was how to generate it, not what actually what it is. Can anybody give a simple explanation of what this key hash actually is and why Facebook needs you to generate one to run samples and your own application?
Can anybody give a simple explanation of what this key hash actually is..
The key hash is a machine specific security check for authenticity. If you use multiple machines for development of the application, you need to add and save multiple key hash to your profile to authenticate every machine.
From the Facebook Documentation page:
..The key hash is used by Facebook as a security check for authenticity. By default, the app's package is signed with a machine specific debug key. When publishing the app it is typically signed with a different, release key. Therefore, you want to make sure you have the hashes of all the related keys set on Facebook...
...Note that you can add multiple key hashes here if you are developing with multiple machines. You will now be able to compile and run all of the authentication-based samples on your emulator without issue.....
(Emphasis mine)
Why does Facebook need you to generate one in order to run samples and your own application?
It's an authentication key to identify registered developers.
How to get key hash of your device?
If your using eclipse then go into window menu > preferences > android > build >
then on right side you will get your machines md5 and sha key which is your
hash key for facebook i think you need to provide your SHA key as a hash key for facebook
this is the very simple way to get your key hash rather than complex command tool process
what is key hash?
it is key associated with your device which is unique key to identify your device so when you provide it to facebook (in your case facebook) then they generte application key against your keyhash so only your machine able to generate the apk with runable output i mean facebook functionality will able to run with its full functionality
such kind of key hash also needed in google project also
NOTE: Never disclose your keyhash to anyone
hope this information will clear your doubts happy coding :)
I am a final year student, i am trying to provide higher level of security at web login time for clients. So, i am looking for fingerprint authentication. Which means, wherever client wants to login he/she has to login using his/her fingerprint. (Assuming client is using digital persona personal fingerprint reader for finger scan). So, is it possible...? if it is, then how..?? Because, i googled my problem , but didn't get helpful material to implement on my project.
Unless your fingerprint reader specifically has support for this functionality, chances are that it's not possible. As a general rule, web pages are intentionally prevented from having direct access to hardware.
Also, see the comments on Online fingerprint authentication for some reasons why fingerprint authentication may not be quite so awesome as it sounds.
If you can access the fingerprint scanner from Java in the browser security context, then you could use Digital Persona's drivers. A problem may arise in that you will likely not be able to access the scanner from the browsers security context without the blessing of the user. Additionally, the Digital Persona drivers may require that you install extra software on the client's machine.
You would need:
A fingerprint capturing device (something like 30 USD to a few hundred USD depending on the spec)
A fingerprint matching SDK (download one that is in the public domain here)
Then you write:
Client code that captures and submits fingerprint images.
Server code that receives a person's fingerprint image at registration, converts that into minutiae data, checks that quality of the image/minutiae to make sure the fingerprint minutiae is usable, then stores it in the DB.
Receives a person's fingerprint image at login, converts that into minutiae data and matches that with the fingerprint in the DB by calling the matching library. Usually you will get a matching score back, with which you can decide whether you consider it the same identity by using a threshold (if score > threshold then authenticate, etc.)
That's the basic idea. The link I provided should have all the libraries you need. Note also that you might need to process the image captured by the capturing device so that you can use it with the libraries.
Biometrics isn't easy. Even if you have the libraries, you can't just use them without careful planning/tuning etc. So it's not like you are good to go to build a production app. just because you have these libraries. It's quite different from say, using Hibernate as a library. So if you are just interested in quickly adding this functionality on your app., you should reconsider because it will take a lot of work to make this work. If you are prepared to understand how these libraries work, play around with image processing, learn about biometrics etc., then it might be fun :)
There are probably libraries out there that you can buy (probably together with the capturing hardware) which will make this process much easier, but they are very expensive.
I have to control access to a system based on fingerprint recognition in PHP.
But I do not know what would be the best approach to do this...
I was searching for a device and software, and maybe this will the one I'll use:
U.are.U 4500 Fingerprint Reader digital persona
This software use somekind of SDK, so java must be used, Is there a way to make a bridge between php and java?.
I am not expert in java web services, but if this is the only way, How to control fingerprint?
Does the device returns an image, or a md5 string, or How does it work, how to read this in php?
What is your experience in this kind of thing...
There's another dimension to this, too.
When you say "PHP", I imagine you're probably talking HTTP web server/client web browser interaction (with PHP on the server).
The Digital Persona (DP) device, however, is usually over on the client.
I've actually used Digital Persona (probably a different device and a different SDK than yours), but the principle is probably similar. You plug the device into the PC's USB port, and the DP SDK controls the device, scans the thumbprint, compares it to other fingerprint images you've "registered" (in a database, a set of image files, whatever), and reports back whether or not there's a match. This all occurs on the CLIENT side.
SUGGESTION:
Your best bet might be:
1) Code your server side stuff in PHP, as you're doing now
2) Code your DP interaction as a JAVA APPLET
3) You DON'T necessarily need to "call Java from PHP" (or vice versa). Instead, all you need to do is:
invoke the applet from the PHP pages you serve, and
Have the applet communicate with the web server
Here's one example of how you might approach this:
http://www.devdaily.com/java/edu/pj/pj010023
What I believe as procedure to be done is:
Create a folder for storing fingerprints of authorised users;
When a fingerprint is inserted to login,
Retrieve the stored fingerprint of the user using php code $a;
Change the fingerprint of the current user into a php code $b;
Compare the two codes $a and $b
If $a != $b then
Give error msg,
If $a == $b then allow entry into system.
You may work on with me to achieve this in php as java is Greek to me.
Thank you.