EncryptionHelper for encrypting json file

Add below code in a Java file named EncryptionHelper.java.



import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Base64;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class EncryptionHelper {

    // Derive AES SecretKey from passphrase
    public static SecretKey deriveKeyFromPassphrase(String passphrase, byte[] salt) throws Exception {
        int iterations = 100000;
        int keyLength = 256;
        KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), salt, iterations, keyLength);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        byte[] keyBytes = factory.generateSecret(spec).getEncoded();
        return new SecretKeySpec(keyBytes, "AES");
    }

    // Encrypt file
    public static void encryptSelectedFile(Context context, Uri inputUri, SecretKey secretKey, String outputFileName) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] iv = cipher.getIV();

        ContentValues values = new ContentValues();
        values.put(MediaStore.Downloads.DISPLAY_NAME, outputFileName);
        values.put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream");
        values.put(MediaStore.Downloads.IS_PENDING, 1);

        ContentResolver resolver = context.getContentResolver();
        Uri collection = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
        Uri fileUri = resolver.insert(collection, values);

        try (
            ParcelFileDescriptor pfd = resolver.openFileDescriptor(fileUri, "w");
            FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
            CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, cipher);
            InputStream inputStream = resolver.openInputStream(inputUri)
        ) {
            fileOutputStream.write(iv);

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                cipherOutputStream.write(buffer, 0, bytesRead);
            }
            cipherOutputStream.flush();
        }

        values.clear();
        values.put(MediaStore.Downloads.IS_PENDING, 0);
        resolver.update(fileUri, values, null, null);

        Toast.makeText(context, "File encrypted to: " + fileUri.toString(), Toast.LENGTH_LONG).show();
    }

    // Decrypt encrypted file and save output to Downloads
    public static void decryptSelectedFile(Context context, Uri encryptedFileUri, SecretKey secretKey, String outputFileName) throws Exception {
        ContentResolver resolver = context.getContentResolver();

        try (InputStream inputStream = resolver.openInputStream(encryptedFileUri)) {
            byte[] iv = new byte[12];
            if (inputStream.read(iv) != iv.length) {
                throw new IllegalArgumentException("Invalid IV in encrypted file");
            }

            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmSpec);

            ContentValues values = new ContentValues();
            values.put(MediaStore.Downloads.DISPLAY_NAME, outputFileName);
            values.put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream");
            values.put(MediaStore.Downloads.IS_PENDING, 1);

            Uri collection = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
            Uri decryptedFileUri = resolver.insert(collection, values);

            try (
                ParcelFileDescriptor pfd = resolver.openFileDescriptor(decryptedFileUri, "w");
                FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
                CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher)
            ) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = cipherInputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, bytesRead);
                }
                fileOutputStream.flush();
            }

            values.clear();
            values.put(MediaStore.Downloads.IS_PENDING, 0);
            resolver.update(decryptedFileUri, values, null, null);

            Toast.makeText(context, "File decrypted to: " + decryptedFileUri.toString(), Toast.LENGTH_LONG).show();
        }
    }
    
    // Decrypt the file to a String
    public static String decryptToString(InputStream encryptedInputStream, SecretKey secretKey) throws Exception {
        // Read the 12-byte IV from the beginning of the encrypted input
        byte[] iv = new byte[12];
        if (encryptedInputStream.read(iv) != iv.length) {
            throw new IllegalArgumentException("Invalid IV in encrypted input");
        }

        // Initialize AES-GCM Cipher for decryption
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmSpec);

        // Use CipherInputStream to decrypt the input stream
        try (
            CipherInputStream cipherInputStream = new CipherInputStream(encryptedInputStream, cipher);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
        ) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = cipherInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            return outputStream.toString(StandardCharsets.UTF_8.name());
        }
    }
    

    // Get file name from Uri
    public static String getFileNameFromUri(Context context, Uri uri) {
        String result = null;
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            try {
                if (cursor.moveToFirst()) {
                    int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                    if (nameIndex != -1) {
                        result = cursor.getString(nameIndex);
                    }
                }
            } finally {
                cursor.close();
            }
        }
        return result;
    }
} 


Comments

  1. Illslick’s website reflects his authenticity and dedication as an artist. From intuitive navigation to exclusive music content, fans can easily explore his creative world, enjoy his tracks, and gain a deeper appreciation for his unique voice and vision.

    ReplyDelete
  2. PopdengClick is a fun and engaging platform that brings joy to users through its interactive clicker game. The seamless interface, playful design, and user-friendly navigation make every click a delightful experience worth exploring.

    ReplyDelete

Post a Comment

Popular posts from this blog

Simple car racing android game in Sketchware

How to enable upload from webview in Sketchware?

Simple Audio recorder app in Sketchware

Custom dialog box in Sketchware using CustomView

How to enable download in webview in Sketchware apps?