package org.geeksforgeeks.demo;
import android.content.ContextWrapper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.InvalidKeyException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.SecretKeySpec;
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private Button encBtn;
private Button decBtn;
// AES encryption key - must be 16, 24, or 32 bytes in length for AES-128, AES-192, or AES-256 respectively
private final String secretKey = "MySecretKey12345";
// Registering an image picker activity to allow the user to select an image from device storage
private final ActivityResultLauncher<String> imagePickerLauncher =
registerForActivityResult(new ActivityResultContracts.GetContent(), this::onImagePicked);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize views
imageView = findViewById(R.id.imageView);
encBtn = findViewById(R.id.encryptButton);
decBtn = findViewById(R.id.decryptButton);
// Set click listener for encrypt button
encBtn.setOnClickListener(v -> {
// Launch image picker to select image for encryption
imagePickerLauncher.launch("image/*");
});
// Set click listener for decrypt button
decBtn.setOnClickListener(v -> {
try {
// Attempt to decrypt and display the image
decrypt();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "Decryption failed", Toast.LENGTH_SHORT).show();
}
});
}
// Callback when an image is picked
private void onImagePicked(Uri uri) {
if (uri != null) {
try {
// Get input stream of the selected image
InputStream inputStream = getContentResolver().openInputStream(uri);
// Encrypt the image using the input stream
encrypt(inputStream);
Toast.makeText(this, "Image encrypted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "Encryption failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
// Returns a directory where encrypted/decrypted images will be stored
private File getPhotoDirectory() {
ContextWrapper contextWrapper = new ContextWrapper(this);
return contextWrapper.getExternalFilesDir(Environment.DIRECTORY_DCIM);
}
// Returns file reference for the encrypted image
private File getEncryptedFile() {
return new File(getPhotoDirectory(), "encfile.png");
}
// Returns file reference for the decrypted image
private File getDecryptedFile() {
return new File(getPhotoDirectory(), "decfile.png");
}
// Encrypts the image from the input stream using AES encryption
private void encrypt(InputStream inputStream) throws Exception {
File encryptedFile = getEncryptedFile();
// Create AES key specification
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "AES");
// Initialize cipher in encrypt mode
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Write encrypted data to file
try (CipherOutputStream cos = new CipherOutputStream(new FileOutputStream(encryptedFile), cipher)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
cos.write(buffer, 0, bytesRead);
}
} finally {
inputStream.close();
}
}
// Decrypts the previously encrypted image file and displays it in the ImageView
private void decrypt() throws Exception {
File encryptedFile = getEncryptedFile();
File decryptedFile = getDecryptedFile();
// Create AES key specification
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "AES");
// Initialize cipher in decrypt mode
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
// Decrypt data and write it to the decrypted file
try (
CipherInputStream cis = new CipherInputStream(new FileInputStream(encryptedFile), cipher);
FileOutputStream fos = new FileOutputStream(decryptedFile)
) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = cis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
// Load and display the decrypted image if it exists
if (decryptedFile.exists()) {
Bitmap bitmap = BitmapFactory.decodeFile(decryptedFile.getAbsolutePath());
// Load bitmap into ImageView using Glide
Glide.with(this).load(bitmap).into(imageView);
Toast.makeText(this, "Decryption successful", Toast.LENGTH_SHORT).show();
}
}
}