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. 

Send Encrypted SMS using Android

You may need to send a secure SMS to your friend over the GSM network. Following is a Tutorial of how you can build Secure SMS messenger using Android.

You can find the How we can receive these secure SMS from this link.

First and foremost, we need to configure the Manifest file with correct permissions.
   
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.priya.sendsms_mis023" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="23"/>
    <uses-permission
        android:name="android.permission.SEND_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>
    </application>

</manifest>


The most important part is acquire correct permission using
android:name="android.permission.SEND_SMS"

Next, we will take a look at the UI(View) part of the application. It is very simple and all you need to do is add couple of Edit text views and a button to send the encrypted 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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView android:text="Enter Message" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:layout_below="@+id/textView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView android:text="Enter Phone Number" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:id="@+id/textView2" />


    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editTextNumber"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView2"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send"
        android:id="@+id/button"
        android:layout_below="@+id/editTextNumber"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />


</RelativeLayout>




Next , we will take a look at how we can do the Encryption part. So I came up with a separate class for this using AES.
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) {

                key = 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;
    }
}


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.
encrypt and decrypt methods in this class itself in order perform all cryptography operations.
The generateKey() function would generate the reuired key based on the initial keyValue and the encryption algorithm which AES in this instance.

Finally, lets examine the main Activity class.
public class MainActivity extends AppCompatActivity {

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

        final Button button = (Button) findViewById(R.id.button);
        final EditText tvMessage=(EditText)findViewById(R.id.editText);
        final EditText tvNumber=(EditText)findViewById(R.id.editTextNumber);
        final String SENT = "SMS_SENT";
        final String DELIVERED = "SMS_DELIVERED";

        final PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
                new Intent(SENT), 0);

        final PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
                new Intent(DELIVERED), 0);


        registerReceiver(new BroadcastReceiver(){
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode())
                {
                    case Activity.RESULT_OK:
                        Toast.makeText(getBaseContext(), "SMS sent",
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                        Toast.makeText(getBaseContext(), "Generic failure",
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                        Toast.makeText(getBaseContext(), "No service",
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                        Toast.makeText(getBaseContext(), "Null PDU",
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        Toast.makeText(getBaseContext(), "Radio off",
                                Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        }, new IntentFilter(SENT));


        registerReceiver(new BroadcastReceiver(){
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode())
                {
                    case Activity.RESULT_OK:
                        Toast.makeText(getBaseContext(), "SMS delivered",
                                Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        Toast.makeText(getBaseContext(), "SMS not delivered",
                                Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        }, new IntentFilter(DELIVERED));

        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                try {
                    String msg = tvMessage.getText().toString();
                    String phoneNumber = tvNumber.getText().toString();
                    AESEncrypt aes = new AESEncrypt(256);
                    String base64 = Base64.encodeToString(aes.encrypt(msg), Base64.DEFAULT);
                    SmsManager smsManager = SmsManager.getDefault();
                    smsManager.sendTextMessage(phoneNumber, null, base64, sentPI, deliveredPI);

                }
                catch(Exception ex)
                {}
            }
        });


    }

    @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);
    }
}


I used the smsManager class to send the Message across the network. This is the simplest SMS sender in Android. There are two BroadcastReceivers where it can track what is actually happens to the SMS ending process once user clicks the send button.

Following is the Final Screenshot of the application.



Note : If you are sending the SMS to another emulator running on your desktop, you need to specify the port number of that emulator as the phone number. To get a specific port number for the emulator use Android Device Monitor tool.

You can Download the source code from this location.

Monday, 24 August 2015

.Net Data Annotations : Add composite Primary Key Code First

Following is the way we can add composite primary key for an entity using Data Annotations.

    
        [Key, Column(Order = 0)]
        [Display(Name = "Year")]
        [Range(2015, 2050)]
        public int Year { get; set; }

        [Key, Column(Order = 1)]
        [Range(1, 12)]
        [Display(Name = "Month")]
        public int Month { get; set; } 


Friday, 21 August 2015

REST Architecture : Scrammed explanation

If you want to take a glance @ Rest architecture , following is a brief definition with constraints.

Rest is an Architectural design pattern and not a standard or design methodology.

Roy Fielding is the person who defines REST as follows (~70's)
"Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use."

Simply , a web page represent a state and by clicking a hyperlink you can do the state transfer into a different page.

Following are the Architectural Constraints of REST.

  1. Uniform Interface : Each call is Independent
  2. Statelessness : State is never managed in the server. 
  3. Client-Server : Highly decoupled
  4. Cacheable : Each response must define itself as cacheable or not
  5. Layered System : Client is not sure about the direct connection to the server   
  6. Code on Demand : Server can customize the client functionality without re-writing 
HATEOAS is a terminology that goes with REST. following is the acronym. 

"Hypermedia as the Engine of Application State"

Hypermedia  is a generalization of hypertext along with other media types. This also describes that the API is Self-documenting, very dynamic . ie : Allows changes to API without having to rewrite the client. 

Thursday, 20 August 2015

Identify DB Entity exceptions

When the app throws an entity exception, it would give a generic details about the error. By using following exception handling block , we would be able to find particular exception in-detail.

    
   catch (DbEntityValidationException Ex)
            {
                foreach (var errors in Ex.EntityValidationErrors)
                {
                    foreach (var validationError in errors.ValidationErrors)
                    {
                        Trace.TraceInformation("Property: {0} Error: {1}",
                                                validationError.PropertyName,
                                                validationError.ErrorMessage);
                    }
                }
            }


Add validation error to MVC Controller and display the error in View

Following code would add error to the model based on some logic in the Controller.
In the Controller
    
   if ((leaveSummary.AnnualTaken + numOfDays) > leaveSummary.Annual)
       ModelState.AddModelError("Leave", "Annual Leave exhausted !");
   else
       leaveSummary.AnnualTaken = leaveSummary.AnnualTaken + numOfDays;

AddModelError is the method we are using to add the new error.
To display this view in the model we need to do following in the cshtml
    
        
@if (!ViewData.ModelState.IsValid) { @ViewData.ModelState["Leave"].Errors[0].ErrorMessage }

Custom compare Validate in the MVC model

We can use data annotations for the model level validations for most scenarios.  There are situations where we need to go beyond than data annotation validations and following is a data comparison example where we need to use extensive validations.

In this example we are using IValidatableObject in our model class in order to implement the date compare validation.

    
   public class LeaveApply : IValidatableObject
    {
        [Key]
        [HiddenInput(DisplayValue = false)]
        public int LeaveKey { get; set; }

        [Display(Name = "Employee")]
        public int EmployeeId { get; set; }

        [ForeignKey("EmployeeId")]
        public Employee Employee { get; set; }
      

        [Display(Name = "Date From")]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime DateFrom  { get; set; }

        [Display(Name = "Date To")]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime DateTo { get; set; }

       

        public IEnumerable< ValidationResult>  Validate(ValidationContext validationContext)
        {
            if (DateTo < DateFrom)
            {
                yield return new ValidationResult("Date To must be greater than Date From");
            }
        }
    }