Sunday, November 17, 2024
Google search engine
HomeLanguagesJavaHow to Encrypt and Decrypt Images in Android?

How to Encrypt and Decrypt Images in Android?

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
    xmlns:tools="http://schemas.android.com/tools"
    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.ContextWrapper
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.*
import javax.crypto.Cipher
import javax.crypto.CipherInputStream
import javax.crypto.CipherOutputStream
import 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:

RELATED ARTICLES

Most Popular

Recent Comments