From 91e0d50c0ad142d2533541b6199a06e7e4ec4b7a Mon Sep 17 00:00:00 2001 From: Kshitij <160704796+kshitij-ka@users.noreply.github.com> Date: Thu, 3 Jul 2025 02:26:46 +0530 Subject: [PATCH] Implement AES-GCM file encryption per user - EncryptionService uses PBKDF2 to derive a key from user password and salt. - AES-GCM encryption with 128-bit tag and 12-byte IV. - Ready for streaming encryption to/from HDFS without temp files. --- .../security/EncryptionService.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/com/skycrate/backend/skycrateBackend/security/EncryptionService.java diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/security/EncryptionService.java b/src/main/java/com/skycrate/backend/skycrateBackend/security/EncryptionService.java new file mode 100644 index 0000000..33d53ac --- /dev/null +++ b/src/main/java/com/skycrate/backend/skycrateBackend/security/EncryptionService.java @@ -0,0 +1,42 @@ +package com.skycrate.backend.skycrateBackend.security; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.*; +import java.security.SecureRandom; +import java.util.Base64; + +public class EncryptionService { + + private static final int KEY_LENGTH = 256; + private static final int ITERATIONS = 65536; + private static final int SALT_LENGTH = 16; + private static final int IV_LENGTH = 12; + + public static byte[] generateSalt() { + byte[] salt = new byte[SALT_LENGTH]; + new SecureRandom().nextBytes(salt); + return salt; + } + + public static SecretKey deriveKey(String password, byte[] salt) throws Exception { + PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH); + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); + } + + public static byte[] encrypt(byte[] plaintext, SecretKey key, byte[] iv) throws Exception { + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + GCMParameterSpec spec = new GCMParameterSpec(128, iv); + cipher.init(Cipher.ENCRYPT_MODE, key, spec); + return cipher.doFinal(plaintext); + } + + public static byte[] decrypt(byte[] ciphertext, SecretKey key, byte[] iv) throws Exception { + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + GCMParameterSpec spec = new GCMParameterSpec(128, iv); + cipher.init(Cipher.DECRYPT_MODE, key, spec); + return cipher.doFinal(ciphertext); + } +} \ No newline at end of file