google-site-verification: google61fe8ba583a51912.html
File Encryption Tool in Java

A comprehensive guide to building a secure file encryption and decryption tool in Java using modern cryptographic practices.

Overview

This tool provides a command-line interface for encrypting and decrypting files using strong encryption algorithms like AES with proper key management and security considerations.

Complete Implementation

1. Main Encryption Tool Class

package com.fileencryptor; import javax.crypto.*; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.*; import java.security.spec.KeySpec; import java.util.Arrays; import java.util.Scanner; /** * Secure File Encryption Tool using AES-GCM mode * Provides encryption and decryption functionality with password-based key derivation */ public class FileEncryptionTool { // Encryption parameters private static final String ALGORITHM = "AES"; private static final String TRANSFORMATION = "AES/GCM/NoPadding"; private static final int AES_KEY_SIZE = 256; private static final int GCM_TAG_LENGTH = 128; private static final int GCM_IV_LENGTH = 12; // 96 bits for GCM private static final int SALT_LENGTH = 16; private static final int ITERATION_COUNT = 65536; /** * Encrypts a file using password-based encryption */ public static void encryptFile(String inputFile, String outputFile, String password) throws Exception { // Generate random salt and IV SecureRandom secureRandom = new SecureRandom(); byte[] salt = new byte[SALT_LENGTH]; byte[] iv = new byte[GCM_IV_LENGTH]; secureRandom.nextBytes(salt); secureRandom.nextBytes(iv); // Derive AES key from password SecretKey secretKey = deriveKey(password, salt); // Initialize cipher for encryption Cipher cipher = Cipher.getInstance(TRANSFORMATION); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv); cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec); try (FileInputStream fis = new FileInputStream(inputFile); FileOutputStream fos = new FileOutputStream(outputFile)) { // Write salt and IV to the beginning of the output file fos.write(salt); fos.write(iv); // Encrypt the file content try (CipherOutputStream cos = new CipherOutputStream(fos, cipher)) { byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { cos.write(buffer, 0, bytesRead); } } } System.out.println("File encrypted successfully: " + outputFile); } /** * Decrypts a file using password-based decryption */ public static void decryptFile(String inputFile, String outputFile, String password) throws Exception { try (FileInputStream fis = new FileInputStream(inputFile); FileOutputStream fos = new FileOutputStream(outputFile)) { // Read salt and IV from the beginning of the encrypted file byte[] salt = new byte[SALT_LENGTH]; byte[] iv = new byte[GCM_IV_LENGTH]; if (fis.read(salt) != SALT_LENGTH || fis.read(iv) != GCM_IV_LENGTH) { throw new IllegalArgumentException("Invalid encrypted file format"); } // Derive AES key from password and salt SecretKey secretKey = deriveKey(password, salt); // Initialize cipher for decryption Cipher cipher = Cipher.getInstance(TRANSFORMATION); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv); cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec); // Decrypt the file content try (CipherInputStream cis = new CipherInputStream(fis, cipher)) { byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = cis.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } } } System.out.println("File decrypted successfully: " + outputFile); } /** * Derives a secure AES key from password using PBKDF2 */ private static SecretKey deriveKey(String password, byte[] salt) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, AES_KEY_SIZE); SecretKey tmp = factory.generateSecret(spec); return new SecretKeySpec(tmp.getEncoded(), ALGORITHM); } /** * Generates a secure random AES key for key file usage */ public static void generateKeyFile(String keyFilePath) throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM); keyGen.init(AES_KEY_SIZE); SecretKey secretKey = keyGen.generateKey(); try (FileOutputStream fos = new FileOutputStream(keyFilePath)) { fos.write(secretKey.getEncoded()); } System.out.println("Key file generated successfully: " + keyFilePath); } /** * Calculates file hash for integrity verification */ public static String calculateFileHash(String filePath) throws Exception { MessageDigest digest = MessageDigest.getInstance("SHA-256"); try (FileInputStream fis = new FileInputStream(filePath)) { byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { digest.update(buffer, 0, bytesRead); } } byte[] hash = digest.digest(); StringBuilder hexString = new StringBuilder(); for (byte b : hash) { hexString.append(String.format("%02x", b)); } return hexString.toString(); } }

2. Command Line Interface

/** * Command Line Interface for the File Encryption Tool */ public class EncryptionCLI { private static final Scanner scanner = new Scanner(System.in); public static void main(String[] args) { System.out.println("=== Secure File Encryption Tool ==="); System.out.println("Using AES-256-GCM with PBKDF2 key derivation"); while (true) { printMenu(); String choice = scanner.nextLine(); try { switch (choice) { case "1": handleEncryption(); break; case "2": handleDecryption(); break; case "3": handleKeyGeneration(); break; case "4": handleIntegrityCheck(); break; case "5": System.out.println("Exiting... Goodbye!"); return; default: System.out.println("Invalid choice. Please try again."); } } catch (Exception e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } System.out.println(); } } private static void printMenu() { System.out.println("1. Encrypt a file"); System.out.println("2. Decrypt a file"); System.out.println("3. Generate key file"); System.out.println("4. Verify file integrity"); System.out.println("5. Exit"); System.out.print("Choose an option: "); } private static void handleEncryption() throws Exception { System.out.print("Enter input file path: "); String inputFile = scanner.nextLine(); System.out.print("Enter output file path: "); String outputFile = scanner.nextLine(); System.out.print("Enter encryption password: "); String password = scanner.nextLine(); // Verify input file exists if (!Files.exists(Paths.get(inputFile))) { throw new FileNotFoundException("Input file not found: " + inputFile); } FileEncryptionTool.encryptFile(inputFile, outputFile, password); // Calculate and display hash for verification String hash = FileEncryptionTool.calculateFileHash(outputFile); System.out.println("Encrypted file SHA-256: " + hash); } private static void handleDecryption() throws Exception { System.out.print("Enter encrypted file path: "); String inputFile = scanner.nextLine(); System.out.print("Enter output file path: "); String outputFile = scanner.nextLine(); System.out.print("Enter decryption password: "); String password = scanner.nextLine(); FileEncryptionTool.decryptFile(inputFile, outputFile, password); // Verify decryption was successful by checking file integrity String hash = FileEncryptionTool.calculateFileHash(outputFile); System.out.println("Decrypted file SHA-256: " + hash); } private static void handleKeyGeneration() throws Exception { System.out.print("Enter key file path: "); String keyFile = scanner.nextLine(); FileEncryptionTool.generateKeyFile(keyFile); System.out.println("Keep this key file secure and secret!"); } private static void handleIntegrityCheck() throws Exception { System.out.print("Enter file path to verify: "); String filePath = scanner.nextLine(); String hash = FileEncryptionTool.calculateFileHash(filePath); System.out.println("File SHA-256 hash: " + hash); } }

3. Advanced Encryption Manager

/** * Advanced encryption manager with additional features */ public class AdvancedEncryptionManager { private static final String ENCRYPTED_EXTENSION = ".encrypted"; private static final String DECRYPTED_EXTENSION = ".decrypted"; /** * Encrypts all files in a directory */ public static void encryptDirectory(String directoryPath, String password) throws Exception { File directory = new File(directoryPath); if (!directory.isDirectory()) { throw new IllegalArgumentException("Path is not a directory: " + directoryPath); } File[] files = directory.listFiles((dir, name) -> !name.endsWith(ENCRYPTED_EXTENSION)); if (files != null) { for (File file : files) { if (file.isFile()) { String outputFile = file.getAbsolutePath() + ENCRYPTED_EXTENSION; FileEncryptionTool.encryptFile(file.getAbsolutePath(), outputFile, password); } } } System.out.println("Directory encryption completed."); } /** * Decrypts all encrypted files in a directory */ public static void decryptDirectory(String directoryPath, String password) throws Exception { File directory = new File(directoryPath); if (!directory.isDirectory()) { throw new IllegalArgumentException("Path is not a directory: " + directoryPath); } File[] files = directory.listFiles((dir, name) -> name.endsWith(ENCRYPTED_EXTENSION)); if (files != null) { for (File file : files) { if (file.isFile()) { String outputFile = file.getAbsolutePath() .replace(ENCRYPTED_EXTENSION, DECRYPTED_EXTENSION); FileEncryptionTool.decryptFile(file.getAbsolutePath(), outputFile, password); } } } System.out.println("Directory decryption completed."); } /** * Securely deletes a file by overwriting it multiple times */ public static void secureDelete(String filePath) throws IOException { File file = new File(filePath); if (!file.exists()) { throw new FileNotFoundException("File not found: " + filePath); } long length = file.length(); try (RandomAccessFile raf = new RandomAccessFile(file, "rws")) { // Overwrite with random data 3 times (DoD 5220.22-M standard) for (int pass = 0; pass < 3; pass++) { raf.seek(0); byte[] randomData = new byte[8192]; SecureRandom secureRandom = new SecureRandom(); long bytesWritten = 0; while (bytesWritten < length) { secureRandom.nextBytes(randomData); int toWrite = (int) Math.min(randomData.length, length - bytesWritten); raf.write(randomData, 0, toWrite); bytesWritten += toWrite; } raf.getFD().sync(); } } // Finally delete the file if (!file.delete()) { throw new IOException("Failed to delete file: " + filePath); } System.out.println("File securely deleted: " + filePath); } }

4. Build Configuration (Maven)

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.fileencryptor</groupId> <artifactId>file-encryption-tool</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- JUnit for testing --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.8.2</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifest> <mainClass>com.fileencryptor.EncryptionCLI</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

Security Features

1. Strong Cryptographic Algorithms

  • AES-256-GCM: Provides both confidentiality and integrity
  • PBKDF2WithHmacSHA256: Secure password-based key derivation
  • SHA-256: File integrity verification

2. Security Best Practices

  • Unique IV per encryption: Prevents pattern analysis
  • Salt for key derivation: Prevents rainbow table attacks
  • Authentication with GCM: Detects tampering
  • Secure random generation: Cryptographically strong randomness

3. Key Management

  • Password-based key derivation with high iteration count
  • Option to generate and use key files
  • Secure memory practices

Usage Examples

Command Line Usage

# Compile and run javac -cp . com/fileencryptor/*.java java com.fileencryptor.EncryptionCLI # Or package with Maven mvn clean package java -jar target/file-encryption-tool-1.0.0-jar-with-dependencies.jar

Programmatic Usage

// Encrypt a file FileEncryptionTool.encryptFile("document.pdf", "document.pdf.encrypted", "securepassword"); // Decrypt a file FileEncryptionTool.decryptFile("document.pdf.encrypted", "document_decrypted.pdf", "securepassword"); // Generate key file FileEncryptionTool.generateKeyFile("secret.key"); // Verify file integrity String hash = FileEncryptionTool.calculateFileHash("important_file.txt");

Security Considerations

  1. Password Strength: Use strong, complex passwords
  2. Key Storage: Never store keys with encrypted data
  3. Secure Deletion: Use the secure delete feature for sensitive files
  4. Backup: Always maintain backups of important files before encryption
  5. Testing: Test encryption/decryption on non-critical files first

This File Encryption Tool provides enterprise-grade security while maintaining ease of use for both command-line and programmatic usage scenarios.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper