4

I need to implement a convenient way to determine, whether a mobile app is being used by a valid customer or not. My customers told me that if they would lose their mobile phone, they definitely would contact the operator and lock the SIM card.

So, it seems natural to bind authentication to the SIM card validity (the app works as long as the correct SIM is present and not locked). Then, in case of loss the customer only needs to lock the SIM card, which he or she would do anyway (because internet banks send SMS for approving transactions to the mobile phone).

I tried to read SIM-card related data, but it works only on some phones and not on others (sometimes I get just empty strings instead of the IMEI number).

How can I implement an authentication mechanism, which is

  1. easy for the user (does not require the user to generate/enter a new password),
  2. provides the app with information whether the currently inserted SIM card is
    1. the same as the SIM that was there at the first start of the application and
    2. not locked?

If it's impossible, what authentication alternatives are there (apart from e-mail/password and phone number with SMS confirmation) ?

Update 1 (11.08.2013 14:17 MSK): One obvious solution is to use the phone number as a login name and server-generated 6-digits number as password.

Then, the authentication would work like this:

  1. At the first run, the user enters his or her mobile phone number.
  2. The server sends him or her a message (SMS) with a 6-digit password.
  3. The user enters that password and the app starts to work.
  4. In regular intervals the app asks the user to renew the password (new passwords are delivered via SMS as well).

What do you think about this option?

Can it be improved somehow?

Glory to Russia
  • 17,289
  • 56
  • 182
  • 325
  • IMEI identifies the device, not the SIM/user data. – Rajesh Aug 10 '13 at 06:39
  • 1
    your second approach is kind of risky. What if the user losses his/her phone? Your approach is a part of two-factor authentication, but you missed the most imperative thing, i.e shared secret. I suggest you to consider using the Android Keystore. Lock it with user pincode, count number of user attempt. Delay the attempt or drop the user credentials after specified number of trails. On top of this SMS approach may strengthen it. Good luck! – samson Sep 02 '13 at 00:20
  • @samson Thanks. What do you think about using user's e-mail address as a communication venue in case of loss (when the user loses the phone, he or she sends an e-mail that blocks the app) ? – Glory to Russia Sep 02 '13 at 07:05
  • Hi Dmitri, I was busy and couldn't able to reply to your question in time. Have you made progress since then? Is there something you may wondering about? – samson Sep 23 '13 at 22:04
  • @samson I think I'll implement authentication via 2 routes - SMS and e-mail. If the phone gets lost, the user will send an e-mail to a certain address and the server will block the app on the stolen phone. – Glory to Russia Sep 24 '13 at 07:37

2 Answers2

5

If you lock your app with SIM properties and requires those properties to be presented for unlocking the app, have you thought about where to store those properties in the app (hard coded, database, file, Preferences,...)? Or are you thinking to contact the server for verification? Both way, you may end up in a complex solution with possible security flaws. SIM serial number is something unique but at the same time it is public, you can't rely on this property to lock your app.

TelephonyManager class is the gateway for accessing SIM properties( this class also exposes users privacy in a number of ways). As of now, there is no android crypro API exposed to perform cryptographic operations in the SIM. But, since your customer can contact the operator, you may consider to ask the operator to sign your app. In that case, you may have a way to use their SIM card as a secure element. There is a discussion on this thread. PIN code based with a limited number of attempts is another way to implement a simple authentication for accessing your app. You may implement this at the application layer without involving the SIM card.

Hope this helps.

Community
  • 1
  • 1
samson
  • 418
  • 5
  • 7
  • Ad *where to store those properties in the app*: I intended to save these data on the server. That is, when the user installs the app, it transfers some identifying information (like SIM number) to my server. Then, whenever the app starts, it contacts the server, and sends to it current identify information. The server compares current data with those from the first run, and tells the Android client that everything is all right. Note that my Android app requires frequent/permanent access to the Internet. – Glory to Russia Aug 11 '13 at 10:17
0

okay. Seems like you have most of the flow already setted in your mind. I am adding a few specific things:

1. Registration

Users will have to explicitly read the SIM serial number which is physically printed on the side of SIM card and have to communicate this serial number to you (in case if you are registering the users manually and offline).. or users could themselves register online by entering this specific SIM serial number (if your registration process is online and user driven). This will be just one time registration.

I am not sure of any way of finding the SIM serial number without taking out the SIM card out of the phone. You can explore it more.

2. Authentication

Now every time the user runs your application, you can read the SIM card related informations like SIM card's Serial Number, Operator Code, Operator Name, Operator Country Code, etc. and communicate this information to your Web Server to authenticate.

You have to use functions getSimOperatorName() , getSimSerialNumbe() , getSimCountryIso() of TelephonyManager for getting these details.

Please note that as @rajesh has already commented that IMEI no. is used to identify the device and not the SIM, so it is of no use if you want the authentication to be SIM card specific.

3. Checking

Besides authentication, you'll have to implement a logic to see the SIM card state (maybe after every specific time interval,, or only at the time when your application is being used).

You'll have to use getSimState() function of TelephonyManager to read the states:

SIM_STATE_NETWORK_LOCKED - Tells that the SIM is locked by the Network operator. (offcourse when the user must have reported to lock the SIM after the SIM lost event. SIM_STATE_ABSENT - Tells that the SIM card is absent.

Accordingly you can quit the application by displaying suitable messages to the user.

This approach can be modified and be used as per to your requirements. I hope that helps you.

Community
  • 1
  • 1
AnniJais
  • 2,760
  • 1
  • 14
  • 9
  • Thanks. I can't use methods `getSimOperatorName() , getSimSerialNumbe() , getSimCountryIso()` because they don't work on all phones (I have 2 test phones and these methods return something only on one of them). – Glory to Russia Aug 19 '13 at 07:54
  • I hope you're using permission - `android.permission.READ_PHONE_STATE` in manifest file. Also could you please mention on which phone this functions are working and on which phone it is not returning anything? – AnniJais Aug 19 '13 at 08:25
  • Yes, I'm using the permission. It works on Alcatel One Touch 4030D and it doesn't work on Highscreen Spark. – Glory to Russia Aug 19 '13 at 09:57
  • okay. even the documentation says that these methods might result null in some cases, though even after exploring I could not find in what situations does these returns null! These functions works for me on Samsung phones! I read somewhere that it is SIM card dependent, i.e, whether the SIM card stores/provides these details or not. I would recommend you to interchange the SIM cards between your both phones and see if it starts working exactly opposite. Then let us know the outcome here. – AnniJais Aug 19 '13 at 11:09