Goal: I am building a app, i want to verify user's mobile number, the way i am using is when user enters the mobile number, I send OTP to that number and ask user to enter the otp to verify the mobile number is in access to user.

The way i am doing this is using users own Sim card to send SMS and doing all procces within the app.

It is as follows: first I generated a small random 6 digit code (OTP)

int otp = new Random().nextInt(900000) + 100000;

then, I send this OTP to the user-entered mobile number that I have to verify. I use the user's own SMS service to do this

SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(user_mobile.getText().toString(),null,"Otp for verification is: "+otp,null,null);

then, I create an Intent, start new activity and pass OTP to new activity

Intent itn = new Intent(MainActivity.this,OtpPage.class);        

and then, the user enters the OTP I sent, and I verify it with the OTP I received from the previous activity using Intent. If both are the same, I verify the mobile number.

Now my question is, Is this a valid way to do this or it contains some security flaws, if yes what security problems may arise here?

  • How can you use the user's SMS service? You just send a text. Are you asking how to send a text? Because that's not a security question.
    – schroeder
    Commented Jan 9, 2022 at 11:33
  • I am not asking how to send SMS, i already did it in above code, My question is normally servers are used to generate otp, send SMS and verify OTP, but if it can be done on client side (APP) why do we need server for such?(Only taking about Android) Commented Jan 9, 2022 at 11:52
  • So ... you want the local app to generate the OTP, then send the OTP to you to ... verify? That's not how this works. Anything on the client side is outside of your control and can be manipulated by the user.
    – schroeder
    Commented Jan 9, 2022 at 11:55
  • but maybe i can check for any changes made in app itself by some sort of signature and if app is modified. my server wont respond to the app. The thing is i am just making mobile verification on user side other than that everything is on server side. Commented Jan 9, 2022 at 12:03

2 Answers 2


Is this a valid way to do this or it contains some security flaws, if yes what security problems may arise here?

You generate the secret on the users device, and then send it to the user. It's probably trivial to rewrite your application to simply tell the server a random phone number, and Yup, this number really verified just fine!

This doesn't offer security, and is just a waste of time. To make this secure, the client should transmit the phone number to the server, and the server should generate a secret and send this via SMS to the provided phone number.

This is not fool proof, as there's avenues for intercepting or hijacking text messages, but it will be magnitudes better than your current scheme.

In addition, as pointed out by bk2204 in a comment, Random() is not secure. It's not meant to be used for secrets, and past codes may reveal future codes, and the seed is commonly the time of the machine - which can be brute forced easily.

  • 1
    And when this is done server side, the OP will need to use a CSPRNG for this and not Random or attackers will be able to guess the code from previous outputs.
    – bk2204
    Commented Jan 9, 2022 at 19:13
  • @bk2204 thanks, added it :) It's a good point!
    – vidarlo
    Commented Jan 9, 2022 at 19:53
  • 1
    An attacker might not even need to re-write the app; the sent message may just appear in the attacker's message history (as a message sent to the target's phone number) when the attacker opens their SMS app!
    – CBHacking
    Commented Jan 10, 2022 at 14:23
  • 1
    @CBHacking Or simply inject themself beteween server and client and observe the traffic, and simply replay the traffic with false phone numbers... there's so many problems with the approach that pointing out all of them is silly.
    – vidarlo
    Commented Jan 10, 2022 at 14:31

In addition to the issues pointed out in the other answer, ever since API level 19 (Android 4.4), using the sendTextMessage function when your app is not the default SMS app will automatically add the sent message to the SMS provider (the central data store of SMS sent and received on the phone, managed by the OS and not part of any individual app). So, all that an attacker would have to do is supply somebody else's number, and then open their SMS app, look for their message history with that person, and enter the code in the last message they sent as though they'd just received it.

Of course, this is only one of the many, many problems with trusting the client like this. The attacker could also steal the code right out of the app as it's generated, spoof the Random (or SecureRandom, once you stop using a predictable PRNG) class so it always generates a known code, steal the code on its way to the server, block the app's message to the server and send their own (with a known code) in its place, spoof the message to the server announcing that the code verified successfully...

And all of that is without even considering that SMS is not very secure to begin with!

  • Thank u everyone for your answers. I have understood that only depending on client app for verification is really so much insecure. Also some points that random function is not secure and SMS APIs are not as well are worth pointing. Commented Jan 10, 2022 at 14:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .