-
Notifications
You must be signed in to change notification settings - Fork 86
Security
- Encryption of database using sqlcipher. Android by default uses sqlite for storage and allows us to browse through the database. Sqlcipher is an adapter on top of sqlite which encrypts the database and no one would be able to decrypt the same.
- The key used for encrypting the database would be generated by the web server(based on the imei of the mobile logging in into the system) and flown into the mobile. So, that means we are not even storing the logged in user's password any where in the android app. This complete approach is well documented here.
- Images captured as part of child records are NOT stored in the database(for performance optimization). Instead, the images are encrypted from the same dbkey which we used for login(which is generated from the webapp) stored in a hidden folder inside the SD card(or the internal memory if SD card not available). Though user can view all the hidden folders and files it would not make any sense for the user as the images would not be usable(we'll NOT be able to render the images with any image rendering tool). One possible option for the user is, he can hard delete the images by browsing into the appropriate hidden location in SD card.
- All communication from android to any connected server can be done either through HTTP or HTTPS. One possible issue with HTTPS is, if the certificate is self signed/if the certificate is not an authorized CA in the default android list it will not be able to communicate. Possible options to overcome the same(which would be a manual process) are documented here. We'll move this to the github wiki asap.
- Followed all the general guidelines in generating the apk around obfuscating(remove unused references in the codebase), zipaligning(zip the entire apk to make it easier to share) and signing(this is yet to be done). Obfuscating/progaurding(making apk code unusable such that no one can decompile the code base) is not be useful for a project like RapidFTR where the codebase is completely opensource.
As we are going to implement some new features like Offline Login, Multi-Server connect from mobile (can connect to only one server at a time, but can connect to different servers after logging out from one server and then to a different server to sync the data thats been synced from the previous server) we are making some changes to the existing security approach on mobile device.
-
These are the basic principles of the new security approach:-
- There will be two permanent databases on the mobile(one for all Verified users and another for all UnVerified users).
- All UnVerified users will share the same encrypted database. An UnVerified user is a user who has signed up and logged onto the mobile, but does not yet have an account on the server. They can only access Child records that they themselves have registered, not any other users child registration records. The database will be encrypted using a DB_KEY(random key) generated on the mobile itself.
- All Verified users (users who are recognized by a server upon synchronization because they have an account on that server) will share the same database (different from UnVerified users's database). Verified users will see Child records that they have registered on the "View Records" pages, and will also be able to search for any other Child record in the "database" or server. This database is encrypted using a DB_KEY generated and stored on the server along with IMEI number and timestamp. The DB_KEY stored on the server for the IMEI will be shared with all other _Verified" user whenever they log in to the mobile through server (network available).
- The DB_KEY's of Verified and UnVerified users are encrypted using their password and stored in the mobile's shared preference along with username to support offline login.
- The DATABASE name is derived from the DB_KEY(may be SHA of the DB_KEY), so when the user login into the mobile again when there is no connectivity we try to check for the username in shared preference and and try to decrypt the DB_KEY using his password, if it is decrypted successfully then the user will get access to the corresponding DATABASE of the DB_KEY.
Here are the different scenarios in which the data is secured and being shared between users and servers
Flow 1:- In this flow there are two servers and one user. An user logs into the mobile for the first time when there is no connectivity and then tries to sync the data to server A, then he tries to connects to server B and again syncing the data.
-
User logins into mobile using his username and password when there is no connectivity to the server. So the user is considered as unauthenticated user and all his data gets into unauthenticated SQLCipher database.
-
Then the user gets the connectivity and tries to sync with server, the server identifies the user as a valid user, as he is a registered user on the server. It accepts the data coming from the mobile and creates a DB_KEY for the IMEI and send it back to mobile along with timestamp.
-
After receiving the signal(DB_KEY) from the server, the user becomes the authenticated user and a new SQLCipher database has been created using the DB_KEY received from server.
Flow 2:- The above user now connects to another server. This scenario has one user and two servers A and B.
-
The above user now connects to another server B. While connecting to the new server he sends his username, password and DB_KEY he already received from Server A along with its timestamp.
-
Server B identifies him as valid user as he is already registered in Server B also. It receives the DB_KEY and store it in couch db along with the IMEI and timestamp.
- New user connects to Server A or Server B, as both the servers already got the DB_KEY for the IMEI it sends back the DB_KEY to the user along with the timestamp if the user is a valid user. Once the new user receive the DB_KEY, he can access the authorized database and this DB_KEY is encrypted with his password and stored on the shared preference for further usage.
Flow 4:- This flow invloves two users and two servers. 1) User 1 logs into Server A. 2) User 2 logs into Server B, then 3) User 1 logs into Server A.
-
First User 1 connects to Server A and sync's his data. During this process he receives the DB_KEY along with timestamp t1 from Server A.
-
Now User 2 connects to Server B and sync's his data. During this process he receives a new DB_KEY along with timestamp t2 from Server B.
-
At this stage there is a new temporary database created for Server B using the DB_KEY received from Server B, we say this as a temporary database because this database will be deleted when server B receives the DB_KEY of the permanent database.
-
Now if User 1 logs into Server B and sends the username/password/DB_KEY/timestamp t1, Server B receives the info as User 1 is a registered user in Server B also. After receiving the DB_KEY from User 1 it checks the DB_KEY it already had for the IMEI. As they are different it compares the timestamp t1 and t2, in our case as t1 > t2 Server B replaces the DB_KEY it already had for the IMEI with the DB_KEY it received from User 1.
-
When User 2, again logs into Server B it receives the new DB_KEY from Server B and copies the data from the temporary database it had for Server B to the permanent database using the new DB_KEY it received from Server B and deletes the temporary database.
-
The above step is necessary to always maintain one single database for all authorized users even when they connect to different servers.