Many times when we are building an android application we have to encrypt the data entered by the user within the android application to maintain the data privacy and security of the application. Along with that we also have to decrypt the data to access it. In this article, we will take a look at How to encrypt and decrypt an image file in our android application. A sample video is given below to get an idea about what we are going to do in this article.
Note: This Android article covered in both Java and Kotlin languages.Â
Step by Step Implementation
Step 1: Create a New Project in Android Studio
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.
Step 2: Working with the activity_main.xml file
Navigate to app > res > layout > activity_main.xml and add the below code to it. Comments are added in the code to get to know in detail.Â
XML
<?xml version="1.0" encoding="utf-8"?><RelativeLayout    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">Â
    <!--image view to display an image-->    <ImageView        android:id="@+id/idIVimage"        android:layout_width="match_parent"        android:layout_height="300dp"        android:layout_margin="10dp"        android:padding="10dp" />Â
    <!--button to encrypt the image-->    <Button        android:id="@+id/idBtnEncrypt"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@id/idIVimage"        android:layout_margin="10dp"        android:text="Encrypt" />Â
    <!--button to decrypt the image-->    <Button        android:id="@+id/idBtnDecrypt"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@id/idBtnEncrypt"        android:layout_margin="10dp"        android:text="Decrypt" />Â
</RelativeLayout> |
Step 3: Working with the MainActivity fileÂ
Navigate to app > java > your app’s package name > MainActivity file and add the below code to it. Comments are added in the code to get to know in detail.Â
Java
package com.gtappdevelopers.encryptionanddecryption;Â
import android.content.ContextWrapper;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;Â
import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;Â
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;Â
import javax.crypto.Cipher;import javax.crypto.CipherInputStream;import javax.crypto.CipherOutputStream;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.SecretKeySpec;Â
public class MainActivity extends AppCompatActivity {Â
    // on below line creating a    // variable for image view and button.    private ImageView imageView;    private Button encBtn, decBtn;Â
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                 // on below line initializing the variables.        imageView = findViewById(R.id.idIVimage);        encBtn = findViewById(R.id.idBtnEncrypt);        decBtn = findViewById(R.id.idBtnDecrypt);Â
        // on below line adding click listener for encrypt button.        encBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // on below line we are picking the image to encrypt it.                Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);                startActivityForResult(i, 1);            }        });Â
        // on below line adding click listener for decrypt button.        decBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // on below line calling decrypt                // method to decrypt our image.                try {                    decrypt();                } catch (Exception e) {                    // displaying a toast message                    // if decryption fails.                    Toast.makeText(MainActivity.this, "Fail to decrypt image", Toast.LENGTH_SHORT).show();                    e.printStackTrace();                }            }        });    }Â
    public void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {        // on below line creating and initializing variable for context wrapper.        ContextWrapper contextWrapper = new ContextWrapper(getApplication());                 // on below line creating a file for getting photo directory.        File photoDir = contextWrapper.getExternalFilesDir(Environment.DIRECTORY_DCIM);                 // on below line creating a new file for encrypted image.        File file = new File(photoDir, "encfile" + ".png");                 // on below line creating input stream for file with file path.         FileInputStream fis = new FileInputStream(file.getPath());                 // on below line creating a file for decrypted image.        File decFile = new File(photoDir, "decfile.png");                 // on below line creating an file output stream for decrypted image.        FileOutputStream fos = new FileOutputStream(decFile.getPath());                 // creating a variable for secret key and passing our secret key        // and algorithm for encryption.        SecretKeySpec sks = new SecretKeySpec("KERQIRUDYTH".getBytes(), "AES");                 // on below line creating a variable        // for cipher and initializing it        Cipher cipher = Cipher.getInstance("AES");                 // on below line initializing cipher and        // specifying decrypt mode to decrypt.        cipher.init(Cipher.DECRYPT_MODE, sks);                 // on below line creating a variable for cipher input stream.        CipherInputStream cis = new CipherInputStream(fis, cipher);                 // on below line creating a variable b.        int b;        byte[] d = new byte[8];        while ((b = cis.read(d)) != -1) {            fos.write(d, 0, b);        }                 // on below line flushing our fos,        // closing fos and closing cis.        fos.flush();        fos.close();        cis.close();                 // displaying toast message.        Toast.makeText(this, "File decrypted successfully..", Toast.LENGTH_SHORT).show();                 // on below line creating an image file        // from decrypted image file path.        File imgFile = new File(decFile.getPath());        if (imgFile.exists()) {            // creating bitmap for image and displaying            // that bitmap in our image view.            Bitmap bitmap = BitmapFactory.decodeFile(imgFile.getPath());            imageView.setImageBitmap(bitmap);        }    }Â
    // on below line creating a method to encrypt an image.    private void encrypt(String path) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {        // on below line creating a variable for file input stream        FileInputStream fis = new FileInputStream(path);                 // on below line creating a variable for context wrapper.        ContextWrapper contextWrapper = new ContextWrapper(getApplication());                 // on below line creating a variable for file        File photoDir = contextWrapper.getExternalFilesDir(Environment.DIRECTORY_DCIM);                 // on below line creating a file for encrypted file.        File file = new File(photoDir, "encfile" + ".png");                 // on below line creating a variable for file output stream.        FileOutputStream fos = new FileOutputStream(file.getPath());                 // on below line creating a variable for secret key.        // creating a variable for secret key and passing our secret key        // and algorithm for encryption.        SecretKeySpec sks = new SecretKeySpec("KERQIRUDYTH".getBytes(), "AES");                 // on below line creating a variable for cipher and initializing it        Cipher cipher = Cipher.getInstance("AES");                 // on below line initializing cipher and        // specifying decrypt mode to encrypt.        cipher.init(Cipher.ENCRYPT_MODE, sks);                 // on below line creating cos        CipherOutputStream cos = new CipherOutputStream(fos, cipher);        int b;        byte[] d = new byte[8];        while ((b = fis.read(d)) != -1) {            cos.write(d, 0, b);        }                 // on below line closing        // our cos and fis.        cos.flush();        cos.close();        fis.close();    }Â
    @Override    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {        super.onActivityResult(requestCode, resultCode, data);        // on below line getting image uri        if (requestCode == 1 && resultCode == RESULT_OK && null != data) {            // on below line getting image uri.            Uri imgUri = data.getData();                        // on below line getting file path            String[] filePath = {MediaStore.Images.Media.DATA};                         // on below line creating a cursor and moving to next.            Cursor cursor = getContentResolver().query(imgUri, filePath, null, null, null);            cursor.moveToFirst();                         // on below line creating an index for column            int columnIndex = cursor.getColumnIndex(filePath[0]);                         // on below line creating a string for path.            String picPath = cursor.getString(columnIndex);                         // on below line closing our cursor.            cursor.close();                         // on below line we are encrypting our image.            try {                encrypt(picPath);                // on below line we are encrypting our image.                Toast.makeText(this, "Image encrypted..", Toast.LENGTH_SHORT).show();            } catch (Exception e) {                e.printStackTrace();                Toast.makeText(this, "Fail to encrypt image : " + e, Toast.LENGTH_SHORT).show();            }        }    }} |
Kotlin
package com.gtappdevelopers.bottomsheetexampleÂ
import android.content.ContextWrapperimport android.content.Intentimport android.graphics.BitmapFactoryimport android.os.Bundleimport android.os.Environmentimport android.provider.MediaStoreimport android.widget.*import androidx.appcompat.app.AppCompatActivityimport java.io.Fileimport java.io.FileInputStreamimport java.io.FileOutputStreamimport java.util.*import javax.crypto.Cipherimport javax.crypto.CipherInputStreamimport javax.crypto.CipherOutputStreamimport javax.crypto.spec.SecretKeySpecÂ
class MainActivity : AppCompatActivity() {Â
    // on below line creating a variable    // for key, image view, and buttons.    val key: String = "KERQIRUDYTH"    lateinit var imageView: ImageView    lateinit var encryptButton: Button    lateinit var decryptButton: ButtonÂ
    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        encryptButton = findViewById(R.id.idBtnEncrypt)        decryptButton = findViewById(R.id.idBtnDecrypt)        imageView = findViewById(R.id.idIVImage)        encryptButton.setOnClickListener {            val i = Intent(                Intent.ACTION_PICK,                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI            )            startActivityForResult(i, 1)        }        decryptButton.setOnClickListener {            // on below line calling            // method to decrypt image.            decrypt()        }    }Â
Â
    fun decrypt() {        // on below line creating and initializing        // variable for context wrapper.        val contextWrapper = ContextWrapper(application)                 // on below line creating a file for getting photo directory.        val photoDir = contextWrapper.getExternalFilesDir(Environment.DIRECTORY_DCIM)                 // on below line creating a new file for encrypted image.        val file = File(photoDir, "encfile" + ".png")                 // on below line creating input stream for file with file path.        val fis = FileInputStream(file.path)                 // on below line creating a file for decrypted image.        val decFile = File(photoDir, "decfile.png")                 // on below line creating an file output        // stream for decrypted image.        val fos = FileOutputStream(decFile.path)        val bytes = key.toByteArray()                 // creating a variable for secret key and passing        // our secret key and algorithm for encryption.        val sks = SecretKeySpec(bytes, "AES")                 // on below line creating a variable for        // cipher and initializing it        val cipher = Cipher.getInstance("AES")                     // on below line initializing cipher and        // specifying decrypt mode to decrypt.        cipher.init(Cipher.DECRYPT_MODE, sks)                 // on below line creating a variable        // for cipher input stream.        val cis = CipherInputStream(fis, cipher)                 // on below line creating a variable b.        var b: Int        val d = ByteArray(8)        while ((b = cis.read(d)) != -1) {            fos.write(d, 0, b)        }                 // on below line flushing our fos,        // closing fos and closing cis.        fos.flush()        fos.close()        cis.close()                 // displaying toast message.        Toast.makeText(this, "Image decrypted successfully..", Toast.LENGTH_SHORT).show()                 // on below line creating an image file       // from decrypted image file path.        val imgFile = File(decFile.path)        if (imgFile.exists()) {            // creating bitmap for image and displaying            // that bitmap in our image view.            val bitmap = BitmapFactory.decodeFile(imgFile.path)            imageView.setImageBitmap(bitmap)        }    }Â
    // on below line creating a method to encrypt an image.    private fun encrypt(path: String) {        // on below line creating a        // variable for file input stream        val fis = FileInputStream(path)                 // on below line creating a variable for context wrapper.        val contextWrapper = ContextWrapper(application)                // on below line creating a variable for file        val photoDir = contextWrapper.getExternalFilesDir(Environment.DIRECTORY_DCIM)                 // on below line creating a file for encrypted file.        val file = File(photoDir, "encfile" + ".png")                 // on below line creating a variable for file output stream.        val fos = FileOutputStream(file.path)                 // on below line creating a variable for secret key.        // creating a variable for secret key and passing our        // secret key and algorithm for encryption.        val sks = SecretKeySpec(key.toByteArray(), "AES")                 // on below line creating a variable for        // cipher and initializing it        val cipher = Cipher.getInstance("AES")                 // on below line initializing cipher and        // specifying decrypt mode to encrypt.        cipher.init(Cipher.ENCRYPT_MODE, sks)                 // on below line creating cos        val cos = CipherOutputStream(fos, cipher)        var b: Int        val d = ByteArray(8)        while ((b = fis.read(d)) != -1) {            fos.write(d, 0, b)        }                  // on below line         // closing our cos and fis.        cos.flush()        cos.close()        fis.close()    }Â
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {        super.onActivityResult(requestCode, resultCode, data)        // on below line getting image uri        if (requestCode == 1 && resultCode == RESULT_OK && null != data) {            // on below line getting image uri.            val imgUri = data.data                         // on below line getting file path            val filePath = arrayOf(MediaStore.Images.Media.DATA)                         // on below line creating a cursor and moving to next.            val cursor = contentResolver.query(imgUri!!, filePath, null, null, null)            cursor!!.moveToFirst()                         // on below line creating an index for column            val columnIndex = cursor.getColumnIndex(filePath[0])                         // on below line creating a string for path.            val picPath = cursor.getString(columnIndex)                         // on below line closing our cursor.            cursor.close()                         // on below line we are encrypting our image.            try {                encrypt(picPath)                // on below line we are encrypting our image.                Toast.makeText(this, "Image encrypted..", Toast.LENGTH_SHORT).show()            } catch (e: Exception) {                e.printStackTrace()                Toast.makeText(this, "Fail to encrypt image : $e", Toast.LENGTH_SHORT).show()            }        }    }} |
Step 4: Adding permissions in the AndroidManifest.xml file
Navigate to the AndroidManifest.xml file and add the below permissions to it to read and write to external storage.
XML
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
Now run your application to see the output of it.Â
Output:
