All about SMS verification using the SMS Retriever API

All About SMS Verification using the SMS Retriever API

Many applications ask users to grant read SMS permission for the automatic detection of OTP. Google found some apps are misusing this permission to read all user messages. It has also been leading to financial fraud and the leaking of personal information. 

To overcome this, Google introduced an SMS retrieval API. Your SMSs are secured with a unique hash key for each application. You automatically get an SMS-based user verification in your Android app, without requiring the user to type verification codes manually and without requiring any extra app permissions – if the key matches the original key

  • Once the user starts the verification process, your app must ask the user to provide a phone number or use the smart lock feature supplied by SDK.
  • After the user enters a valid phone number, you must connect with your server.
  • Simultaneously, you need to start or init the SMS Retrieval API to study the SMS that your server sends to the user’s entered phone number. 
  • The server will send an SMS to the user that will have an OTP to be sent back to your server and a hash key that will identify your app. (we will see more about a hash key generation later in this blog)
  • The device shall detect the SMS, and the Google Play service will decide whether this SMS is for your app or not with the help of a hash key present in the SMS body.
  • After successfully validating the hash, the Google Play service will allow your app to read the SMS code.
  • The app will fetch the OTP from the SMS and send it to your server.
  • The server will verify the OPT, and finally, your app shall complete the verification process successfully.

Integration of SMS Retriever in your Android App

Include the Play Services auth component in your app’s build.gradle file:

It will work in Play Services version 10.2 and the newer ones.

implementation ‘com.google.android.gms:play-services-auth:17.0.0’ implementation ‘com.google.android.gms:play-services-auth-api-phone:17.4.0’ 

1. Get the User’s Phone Number

SDK introduced a beneficial class named “HintRequest.” By using this class, you can show a dialog containing the user’s phone number for selection. This will reduce users’ time to enter phone numbers manually in edit text. The good thing is, for a hint picker, you don’t need to ask for any extra permission. 

2. Start SMS Listener and Send the Number to the Server

To listen to SMS from which the server sends with hash keys and OTP, we have to get an instance of the SmsRetrieverClient object and call startSmsRetriever.  You will find the success and failure class of listeners. This task will last for five minutes. 

After getting the phone number, you need to send it to the server to send a verification code to the user’s mobile. This will be done with your app’s standard HTTP post request.

 3. Receive the OTP in your App

Create a broadcast receiver for receiving messages. You will get the same using the onReceive method. You have to check for SmsRetriever.SMS_RETRIEVED_ACTION.

Don’t forget to register this receiver in the manifest file with the SMS_RETRIEVED  filter. 

4. Send the OTP to your Server

If you find success in the onReceive method in the broadcast receiver, start the process to send OTP to our server for verification. The server will match OTP and will revert success and userID after creating a new user. 

The process to create the app hash key: 

Computing your app’s hash string

Google Play service will identify that the received message is for your app when you enter the hash received in the OTP message generated from the server. The hash is made from the app package name and app public key certificate.

There are two ways to generate a hash. The first is with the help of commands, and the second is by writing code in projects with any Java file. 

Below is an example to command from which we can generate a hash from the production keystore:

keytool -exportcert -alias PlayDeploymentCert -keystore MyProductionKeys.keystore | xxd -p | tr -d “[:space:]” | echo -n com.example.myapp `cat` | sha256sum | tr -d “[:space:]-” | xxd -r -p | base64 | cut -c1-11

The second way is, you can create a class in your project for hash string generation:

public ArrayList<String> getAppSignature() { 
    ArrayList<String> listAppCodes = new ArrayList<>(); 
	try { 
    	String pkgName = getPackageName(); 
        PackageManager pkgManager = getPackageManager(); 
    	Signature[] signatures = packageManager.getPackageInfo(pkgName, 
            	PackageManager.GET_SIGNATURES).signatures; 
     	for (Signature sign: signatures) { 
        	String hashString = hash(packageName, sign.toCharsString()); 
        	if (hashString != null) { 
                listAppCodes.add(String.format("%s", hashString)); 
        	} 
    	} 
	} catch (PackageManager.NameNotFoundException e) { 
        Log.e("”,  e); 
	} 
	return listAppCodes; 
} 
  
 
private static String getHash(String pkgName, String strSgnature) { 
	String appInfoStr = pkgName + " " + strSgnature; 
	try { 
        MessageDigest msgDigest = MessageDigest.getInstance(HASH_TYPE); 
        msgDigest.update(appInfoStr.getBytes(StandardCharsets.UTF_8)); 
    	byte[] hashSignature = msgDigest.digest(); 
    	// truncated into NUM_HASHED_BYTES 
    	hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES); 
String base64HashString = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP); 
    	base64Hash = base64HashString.substring(0, NUM_BASE64_CHAR); 
        Log.d("”, String.format("pkg: %s ---- hash: %s", pkgName, base64HashString)); 
    	return base64HashString; 
	} catch (NoSuchAlgorithmException e) { 
        Log.e(TAG,  e); 
	} 
	return null; 
} 

In the end, we must add the SMS retriever functionality to ease our registration process with security and without harming the users’ privacy. If there’s anything you are not thorough with or require more help with SMS Verification, get in touch with an expert at DEV IT.