I'm building an android app that needs to authenticate with a php service. My current approach is when the user initially logs in, a unique id is generated using uniqid(). This uid is then stored in a table on the database along with their username.The user is then passed back this uid.
Subsequently all further requests to the server will send the the uid and their username, which will be then checked in the database to authenticate the user.
Is this approach OK? or are their massive security holes that I am missing?
A few problems here. For one uniqid() is almost entirely made up of a timestamp and there for very predictable. Instead of just reinventing the wheel you should just use PHP's session_start(). If for some reason you can't use PHP's sessions, then generate a session id using session_id().
Other problems, if your application suffers from sql injection then an attacker can pull the session id out of the database and just login. The reason why passwords are hashed is to slow down an attacker after the database has been compromised, if the attacker has the session id then he doesn't have to crack a password hash to login. (You are hashing passwords right...) One option is to use MySQL's aes_encrypt() on the stored session id's.
Related
I am integrating log in in my app. There is a requirement for log in without internet connection. Means first time when user gets login there will be a web service call for log in authentication but next time the web service call should not be needed it should authenticate from local db of device. First time on log in response I am saving user credentials in local db (means device db using sqlite) and for rest of the attempts I am matching credentials from local db for authentication. For authentication, password is a plan text in local db and I am matching plan passwords. It this good idea/approach to match password as a plan text or I am supposed to be using any encryption? If encryption is required so why is it needed so. I mean when db file is stored internally no one can fetch password.So why encryption is needed?
Never ever store passwords in plain text anywhere. Event when it's local and nobody has access to it.
The better approach is storing it using a hashing algorithm along with salt so the if password is leaked somewhere, no harm should come of it.
You can then hash the input password with the same algorithm and verify it with one you have previously stored.
Here are some links to get you started on hashing:
https://crackstation.net/hashing-security.htm
http://howtodoinjava.com/security/how-to-generate-secure-password-hash-md5-sha-pbkdf2-bcrypt-examples/
I should develop an phonegap application. I need to encrypt my requests to the server side and then decrypt.
HTTPS is not a solution, because I need to sign requests to be sure that the data is not fake. I can use any async cryptography (the app will generate private/public keys and will send public key to the server). But this way I need to keep my private key on the device.
The question is: how I can keep private key on the device securely?
I can use sqlclipher (to encrypt my local SQLite DB) and integrate it into my phonegap app. Great, but here I have to keep secret key for database :)
var db = window.sqlitePlugin.openDatabase({name: "DB", key: "secret1"});
Any one who have access to the phone can get this secret key. So here I have the same issue:)
Please, give me any suggestions.
Thanks!
p.s. app for iOS and Android
You have to differentiate between encryption and authentication.
First, I suggest to use https to encrypt your messages and transfer them securely.
Second, I suggest to use HMAC for authentication of your messages. It basically works like this:
Generate a secret string known to your app and the server at compile time. You store this secret directly in the source code of your app so it is never transmitted to or from the server. This might be the main difference to your private/public key approach: You compile the secret right into your app instead of writing it later in some user accessible storage. "Right into your app" means in the case of Phonegap NOT in your HTML/JS files but in the native source code! You have to bridge the accessor to javascript if necessary.
Set a user id (=key; long, random!) in your app when the user starts your app for the first time. If you want to authenticate your users, you probably have some kind of login/password mechanism. (Store the user id as well as an HMAC generated from the user id and the shared secret on the device. Every time you read the user id, check it against the hash to be sure that the user id was not spoofed.)
In your App
Include a user id in every message.
Include a timestamp in every message.
Calculate the HMAC hash from a string put together from the message, the server address, the request URI, and the shared secret.
Include the hash value in your request header.
On the server side
Check if the timestamp is valid, e. g. not older than 2 minutes or so. This prevents replay attacks (at least after 2 minutes).
Check in your database if the user id is valid.
Calculate the HMAC hash from a string put together from the message, the server address, the request URI, and the shared secret. Including the request URI prevents people to send the same valid request to another URI on your server; e. g. in REST environments it is a big difference if you send the same DELETE request to /comment/1 or /user/1.
Compare it to the hash value submitted in your header, they have to be equal.
If any check fails, send an error. Otherwise send the response.
There is a chance of getting the shared secret and information about the way how you calculate the HMAC hash by decompiling your source code. I see no way to avoid this risk. ...without diving deeper into native development:
iOS Keychain
https://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
Android security features
http://developer.android.com/training/articles/security-tips.html
By default, PhoneGap does not provide the feature of encryption on its own. Devices based on iOs and Android(above Gingerbread version) support full-disk encryption. But this is not available to PhoneGap/Cordova developers.
From the wiki:
PhoneGap is generally limited to the security features of the platform
on which it is running.
Refer to https://github.com/phonegap/phonegap/wiki/Platform-Security
For some JS based solution, give a try at http://code.google.com/p/crypto-js/
I'm working on an app that has PHP classes to connect to the web server for login and other database transactions, and SQLite serves as a local db to store user credentials.
I'm not sure if the SQLite maintains the user session or not but it keeps the login status until the user clicks on the logout button.
How would I implement the session(or something) so that the user can make other database transactions based on the user ID throughout the states?
Some say to establish session in PHP and other say to use preferences.
What would be the best solution for me?
Maybe I shouldn't ask that but, well, are your webservices RESTful or not ?
If they are, I read a lot of discussions about not keeping user sessions on the server, but instead authenticate user at each request (using his credentials or more secured authorization systems).
Otherwise, yes, you can just create PHP sessions server-side when a user is authenticating. You store the session in a specific table, containing a fk_user_id field, and you send back the session_id to the client application (android app in your case) once the authentication process is over. Then the session_id is stored (in user-preferences for example), and sent along with each request in order to retrieve who is asking data, thanks to the sessions table and its fk_user_id field.
I need some advise.
I have a mobile application (Android) and a WebService for it.
When application starts first time - user does some registration process. Then he has a username(Unique). The server give the user a unique userId for internal purposes.
In some features of the application - the user sends requests to the webservice that needs the UserId.
I thought to sends for these request the username and not the userId - meaning that the application will never have the internal userIds, always send the username and the webservice will find the userId itself..... Guess it is better for security issues, disadvantage is that it takes more time in the server side.
Any ideas?
Comments?
For me it makes more since to store both in the android application and use the userid to make requests. I'm not aware of any unsecure aspects of sending the userid. If anything it seems less secure to accept a username because anyone has access to the list of usernames and if they found the service endpoint could possible figure out how to send it someone else's username and retrive info. The userid on the other hand is hidden from the users.
I am creating an app that requires the user to register with a remote server, but I want to hash their password before sending it off to be stored in my database.
I tried using the jBCrypt library, but it created a long hang time while hashing. Are there any other alternatives? What would be the best (and safest) way to hash the passwords without creating a noticeable hang?
Your approach seems to be wrong. Unless you have some special requirements, the usual way to do this is the following (not Android-specific, for any web application):
When the users register, take their password, hash it (using a random salt is also recommended), and save it in the DB. That is done so you don't save the actual password in your DB.
When the user needs to login, you send the actual password to your webapp (use SSL to avoid sending it in the clear), not the hash. On the server, you apply the same hashing algorithm as in step 1, and compare the result to what is in your DB. If they are the same, the user has provided the correct password.
In short, you should do your hashing on the server, not on the Android device.
Avoid saving 3rd party passwords at all cost. Saving them is considered a form of phishing. Try to save an authentication token instead of a raw password that you can get using a method like OAuth.
If you do need to send a password to a database on a webserver, just use HTTPS. This will ensure safe encryption over the wire. Then you can encrypt the password as necessary in the database. This method also ensures that your encryption mechanism is not on the device itself which can be more easily compromised.