Create Android chat message App with End to End AES(Advanced Encryption Standard) method in Firebase

This is a rather a long video (around 1 hour) but it shows complete steps to create an Android Message App with End to End Encryption using AES (Advanced Encryption Standard) method in Firebase Database from scratch. In this video it shows first the steps to create a Firebase database connected to your Android App. Then it moves on and shows how to create a simple layout of your App in Android Studio.

Once the above basics are done then it shows the main coding part. Various settings of gradle files are shown and then Java coding for accessing the database and encrypting and decrypting the messages are shown. For encryption and decryption the AES instance of Android Cipher is used. The message string is first converted into Byte, then encrypted using AES method and then encrypted byte is converted back to String using a standard character set. This encrypted byte string is then stored in the Firebase.

So, as the data stored in the Firebase database is in encrypted form, even if anyone is able to get the access to the database, the actual message will not be readable by the person until s/he has the encryption method and key available with him.

Similarly, on the decryption side, the received string from the database is converted back to byte using the same character set (used on the encryption side). Once the encrypted byte data is available, then the decrypt mode cipher is used to decrypt the data. The decrypted data is then converted back from byte to String readable format. Then that output string, after sorted out in chronological order, is displayed in the listview of our App layout for the user to see.

So, to summarize this is an end-end message App tutorial. This will be helpful for anyone who wants to quickly start building their own chat message App.

The above video is continuation of my initial video tutorial, which showed the process to create the chat App without any encryption. The first part can be seen at:
https://youtu.be/Hn_wfTqFbdg

We will be glad to hear from you regarding any query, suggestions or appreciations at: programmerworld1990@gmail.com

Source Code:

package com.example.myencryptionchatyoutubeapp;

import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class MainActivity extends AppCompatActivity {

    private EditText editText;
    private ListView listView;

    private DatabaseReference databaseReference;

    private String stringMessage;
    private byte encryptionKey[] = {9, 115, 51, 86, 105, 4, -31, -23, -68, 88, 17, 20, 3, -105, 119, -53};
    private Cipher cipher, decipher;
    private SecretKeySpec secretKeySpec;


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

        editText = findViewById(R.id.editText);
        listView = findViewById(R.id.listView);

        try{
            databaseReference = FirebaseDatabase.getInstance().getReference("Message");

            try {
                cipher = Cipher.getInstance("AES");
                decipher = Cipher.getInstance("AES");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            }

            secretKeySpec = new SecretKeySpec(encryptionKey, "AES");

            databaseReference.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                    stringMessage = dataSnapshot.getValue().toString();
                    stringMessage = stringMessage.substring(1,stringMessage.length()-1);

                    String[] stringMessageArray = stringMessage.split(", ");
                    Arrays.sort(stringMessageArray);
                    String[] stringFinal = new String[stringMessageArray.length*2];

                        try {
                            for (int i = 0; i<stringMessageArray.length; i++) {
                                String[] stringKeyValue = stringMessageArray[i].split("=", 2);
                                stringFinal[2 * i] = (String) android.text.format.DateFormat.format("dd-MM-yyyy hh:mm:ss", Long.parseLong(stringKeyValue[0]));
                                stringFinal[2 * i + 1] = AESDecryptionMethod(stringKeyValue[1]);
                            }


                    listView.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, stringFinal));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
        }
        catch (Exception e){
            e.printStackTrace();
        }

    }

    public void sendButton(View view){

        Date date = new Date();
        databaseReference.child(Long.toString(date.getTime())).setValue(AESEncryptionMethod(editText.getText().toString()));
        editText.setText("");

    }

    private String AESEncryptionMethod(String string){

        byte[] stringByte = string.getBytes();
        byte[] encryptedByte = new byte[stringByte.length];

        try {
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            encryptedByte = cipher.doFinal(stringByte);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }

        String returnString = null;

        try {
            returnString = new String(encryptedByte, "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return returnString;
    }

    private String AESDecryptionMethod(String string) throws UnsupportedEncodingException {
        byte[] EncryptedByte = string.getBytes("ISO-8859-1");
        String decryptedString = string;

        byte[] decryption;

        try {
            decipher.init(cipher.DECRYPT_MODE, secretKeySpec);
            decryption = decipher.doFinal(EncryptedByte);
            decryptedString = new String(decryption);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return decryptedString;
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myencryptionchatyoutubeapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:windowSoftInputMode="adjustPan">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="500dp" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="510dp"
        android:ems="10"
        android:gravity="start|top"
        android:hint="@string/type_your_message_here"
        android:inputType="textMultiLine"
        android:autofillHints="" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="310dp"
        android:layout_marginTop="510dp"
        android:onClick="sendButton"
        android:text="@string/send" />
</RelativeLayout>

Top YouTube Comment/ Posts:

how did u to enter evaluate menu..tnks any way
In the debug mode, select the expression you want to evaluate. And then

– Either press Alt+F8

– Or Choose the “Evaluate Expression …” option from right-click context menu.

Hope the above helps. Cheers!
——

You should watch my below video for details on how to debug the source code: https://youtu.be/Y_y2jR1GSC8

21 comments

  1. sir, i want to build an android voice assistant app that can read the given sentence and if i give the command stop and it should stop there and again if i say start then it should start from there so i want to implement this type of code help me

  2. I have a tutorial which shows how to give instructions to your phone using voice command. The tutorial details can be found in the below page:
    https://programmerworld.co/android/how-to-give-voice-command-to-your-phone-from-your-custom-android-app-to-perform-certain-operations/

    Currently, I am working on creating a simple voice assistance Android App. It will be published soon. Will let you know once it is available.

    Good Luck
    Programmer World
    https://www.youtube.com/c/programmerworld

  3. When trying to replicate your code in Android Studio I receive the error

    “Error inflating class android.widget.ListView”

    The project builds fine but does not run.

    • I am not sure why in your code it is trying to inflate the listview. You can simply set the adapter on the listview as shown in the below line of code and it should work:

      listView.setAdapter(new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, stringFinal));

      If the issue is still there then please paste the part of code that is giving error so that we can have check it.

      Cheers
      Programmer World

    • As told in the video also, the key in this tutorial is generated using random number approach. So, one is free to use any randomly generated key code. The only point is that it should be unique and the same key code should be used to decipher or decrypt the encrypted message on receiver side.

      I hope above helps.

      Cheers
      Programmer World

  4. hi, the message already show in db but why in my listview it not showing anything

  5. Message is not showing in listview and firebase database also …I wrote the same code as you what to do?

    • It is most likely because database connection is not working in the App. Debug and check below line of code and see if the databaseReference variables’s value is populated:
      databaseReference = FirebaseDatabase.getInstance().getReference(“Message”);

      If not then check the connection to the database. Try replacing the JSON file from the Firebase database. That may resolve the issue.

      Cheers
      Programmer World

  6. I wrote same code as you but in my listview as well as in database message is not showing please help

    • It is most likely because database connection is not working in your code. Debug and check below line of code and see if the object’s value is populated:
      databaseReference = FirebaseDatabase.getInstance().getReference(“Message”);

      If not then check the connection to the database. Try replacing the JSON file from the Firebase database. That may resolve the issue.

      Cheers
      Programmer World

Leave a Reply