Friday 11 September 2015

Recieve Encrypted SMS using Android

We have discussed how we can send encrypted SMS using Android in this post. Now it is time to analyze how we can decrypt those encrypted SMS using another application. Targeted functionality is when the SMS received , it should spawn the decryption application and show the clear text message to user.

Im using an Android BroadcastReceiver class in order to keep an alert on whats going on the phone. As you know it is running as a background thread in the phone. If there is an incoming SMS it tries decrypt it. First of all lets examine whats in the all important Manifest file.
   

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.priya.recievesms_mis023" >
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".PriyalBroacast">
        <intent-filter android:priority="999" >
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>
    </application>

</manifest>



Permissions are granted to read and receive SMS.
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.READ_SMS"/>
Note that I set the receiver as PriyalBroacast because this would be my Broacast listener class which inherited by BroadcastReceiver. I set up relatively higher value to priority in order to execute this operation before many other operations. action android:name="android.provider.Telephony.SMS_RECEIVED" This line would invoke the broadcast listener in the event of a SMS received.
The Broacast Class
   
public class PriyalBroacast extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        try {

            Bundle smsBundle = intent.getExtras();
            SmsMessage[] msg = null;
            String sms_str = "";
            String mySms = "";
            if (smsBundle != null) {
                Object[] pdus = (Object[]) smsBundle.get("pdus");
                msg = new SmsMessage[pdus.length];

                if(msg.length>0)
                {
                    msg[0] = SmsMessage.createFromPdu((byte[]) pdus[0]);
                    mySms = msg[0].getMessageBody().toString();
                }

                AESEncrypt aes = new AESEncrypt(256);
                mySms = mySms.substring(0, mySms.length() - 1);
                byte[] b= aes.decrypt(Base64.decode(mySms, Base64.DEFAULT));
                String decryptedSMS = new String(b);


                Intent smsShow = new Intent(context, MainActivity.class);
                smsShow.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                smsShow.putExtra("mySms", decryptedSMS);
                context.startActivity(smsShow);


            }
        }
        catch(Exception ex)
        {
           
        }

    }
}

This class would extract the body of the SMS and decrypt it using AES. After a successful decryption, its just call to the MainActivity to show the decrypted message.
Following is the Implementation of the AES Cryptography class.
Note that Im using a static AES Key which is hard coded here. This is not a very good security practice. Instead, We need to store the key securely in the device if we are going to use the Symmetric encryption. I would discuss this in a separate post and this is enough for the time being and for learning purposes.
   
public class PriyalBroacast extends BroadcastReceiver
{
public class AESEncrypt {
    private static Key key=null;
    private static Cipher cipher = null;

    private static String algorithm = "AES";
    private static byte[] keyValue=new byte[] {'0','2','3','4','5','6','7','8','9','1','2','3','4','5','6','7'};//

    public AESEncrypt(int size) throws NoSuchAlgorithmException, NoSuchPaddingException {
        //Generate a key
        try {
            if (key == null) {
                KeyGenerator generator = KeyGenerator.getInstance("AES");
                generator.init(size);
                key = generateKey();//generator.generateKey();
            }
            if (cipher == null) cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        }
        catch(Exception e)
        {}
    }

    public byte[] encrypt(String msg) throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException{
        // encryption pass
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(msg.getBytes());
    }

    public byte[] decrypt(byte[] cipherText) throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException{
        // decryption pass
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }

    private static Key generateKey() throws Exception
    {
        Key key = new SecretKeySpec(keyValue, algorithm);
        return key;
    }
}

Finally the Main Activity class and the simple UI.
   
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent sms_intent=getIntent();
        Bundle b=sms_intent.getExtras();
        TextView tv=(TextView)findViewById(R.id.txtview);
        if(b!=null){

            tv.setText(b.getString("mySms"));
        }

    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Following UI would show the decrypted SMS
   
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    tools:context="com.example.smsreceiver.MainActivity" >

    <TextView
        android:id="@+id/txtview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="5"
        android:singleLine="false"
        android:textSize="20sp"
        />
</RelativeLayout>


If we examine the SMS Inbox in the emulator. We can clearly see the encrypted messages.

You can Download the source code from this location. 

No comments:

Post a Comment