Encryption and Decryption with AES - Kotlin Version

In this tutorial, you will learn how to implement encryption and decryption of strings in an Android app using Kotlin. The tutorial will guide you through the process of setting up AES (Advanced Encryption Standard), a widely used cryptographic algorithm, for securing sensitive data. You'll learn how to encrypt plaintext strings to protect them from unauthorized access and decrypt them back to their original form when needed. This implementation will demonstrate practical encryption techniques in Kotlin, ensuring data security within your Android applications.
Submitted on July 07, 2024

Creating an Android app for encrypting and decrypting strings involves using cryptographic algorithms to secure sensitive information. For this example, we'll use AES (Advanced Encryption Standard) for encryption and decryption, which is commonly used due to its security and efficiency.

Step-by-Step Implementation

1. Update Dependencies

Make sure to include the following dependency for cryptographic operations in your ‘build.gradle’ file:


implementation 'javax.crypto:javax.crypto-api:1.1.1'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'

    

2. Design Layout (activity_main.xml)

Create a simple layout with EditTexts for input text and buttons for encryption and decryption:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <EditText
        android:id="@+id/editTextInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter text to encrypt/decrypt"
        android:inputType="textMultiLine"
        android:minLines="3"
        android:gravity="top"
        android:layout_marginBottom="16dp"/>

    <Button
        android:id="@+id/buttonEncrypt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/editTextInput"
        android:text="Encrypt"
        android:onClick="encryptText"
        android:layout_marginEnd="8dp"/>

    <Button
        android:id="@+id/buttonDecrypt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/editTextInput"
        android:layout_toEndOf="@id/buttonEncrypt"
        android:text="Decrypt"
        android:onClick="decryptText"
        android:layout_marginStart="8dp"/>

    <EditText
        android:id="@+id/editTextOutput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Encrypted/Decrypted text"
        android:inputType="textMultiLine"
        android:minLines="3"
        android:gravity="top"
        android:layout_below="@id/buttonEncrypt"
        android:layout_marginTop="16dp"/>

</RelativeLayout>

    

3. Implement Encryption and Decryption Logic (MainActivity.kt)

Implement the encryption and decryption methods using AES algorithm:


package com.example.installedapps;

import android.os.Bundle;
import android.util.Base64;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class MainActivity extends AppCompatActivity {

    private EditText editTextInput;
    private EditText editTextOutput;

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

        editTextInput = findViewById(R.id.editTextInput);
        editTextOutput = findViewById(R.id.editTextOutput);

        // Add BouncyCastle provider for AES algorithm support
        Security.addProvider(new BouncyCastleProvider());
    }

    // Method to generate AES key
    private SecretKey generateAESKey() {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "BC");
            keyGenerator.init(256);
            return keyGenerator.generateKey();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // Method to encrypt text
    public void encryptText(android.view.View view) {
        try {
            String inputText = editTextInput.getText().toString();

            // Generate AES key
            SecretKey secretKey = generateAESKey();

            // Encrypt the input text
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(inputText.getBytes());

            // Convert encrypted bytes to Base64 for storage or transmission
            String encryptedBase64 = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);

            editTextOutput.setText(encryptedBase64);
        } catch (Exception e) {
            Toast.makeText(this, "Encryption failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }

    // Method to decrypt text
    public void decryptText(android.view.View view) {
        try {
            String encryptedText = editTextOutput.getText().toString();

            // Generate AES key (must be the same key used for encryption)
            SecretKey secretKey = generateAESKey();

            // Decrypt the encrypted text
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] encryptedBytes = Base64.decode(encryptedText, Base64.DEFAULT);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

            String decryptedText = new String(decryptedBytes);

            editTextInput.setText(decryptedText);
        } catch (Exception e) {
            Toast.makeText(this, "Decryption failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
}

    

Explanation:

  • Layout (‘activity_main.xml’): Defines a simple UI with two EditTexts (‘editTextInput’ for input text and ‘editTextOutput’ for encrypted/decrypted text) and two buttons (buttonEncrypt and buttonDecrypt) to trigger encryption and decryption.

  • MainActivity (MainActivity.kt):

    • Initializes views (‘editTextInput’ and ‘editTextOutput’) and adds BouncyCastle provider for AES algorithm support.
    • generateAESKey(): Generates a 256-bit AES key using BouncyCastle provider.
    • encryptText(view: View): Retrieves input text, generates AES key, initializes AES cipher in encryption mode (Cipher.ENCRYPT_MODE), encrypts input text, and converts encrypted bytes to Base64 format for display.
    • decryptText(view: View): Retrieves encrypted text, generates AES key (must be the same key used for encryption), initializes AES cipher in decryption mode (Cipher.DECRYPT_MODE), decrypts Base64-encoded encrypted text, and displays decrypted text in ‘editTextInput’.
  • Security (BouncyCastleProvider): Android's default providers may not support all AES modes, so we add BouncyCastle as a provider (Security.addProvider(BouncyCastleProvider())) to ensure compatibility with AES algorithms.

Running the App:

After completing these steps, run your app on an emulator or physical device. You can enter text in the ‘editTextInput’, encrypt it by tapping Encrypt, and then decrypt it by tapping Decrypt. The ‘editTextOutput’ will display the encrypted or decrypted text accordingly.

This implementation provides a basic example of using AES encryption and decryption in an Android app. For production use, consider additional security measures, such as securely storing encryption keys and handling exceptions appropriately.