From 03bdb5d8986959bc6358fb5931d7e5bd771cfebd Mon Sep 17 00:00:00 2001 From: Sonali2109 Date: Fri, 18 Apr 2025 00:28:45 +0530 Subject: [PATCH] Implemented Encryption and Decryption Needed to be as saved Response --- .../config/JwtAuthenticationFilter.java | 3 - .../services/EncryptionUtil.java | 71 +++++---- .../services/HDFSOperations.java | 140 +++++++++++------- .../skycrateBackend/utils/RSAKeyUtil.java | 30 ++-- 4 files changed, 151 insertions(+), 93 deletions(-) diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/config/JwtAuthenticationFilter.java b/src/main/java/com/skycrate/backend/skycrateBackend/config/JwtAuthenticationFilter.java index 8e47a34..024b6c1 100644 --- a/src/main/java/com/skycrate/backend/skycrateBackend/config/JwtAuthenticationFilter.java +++ b/src/main/java/com/skycrate/backend/skycrateBackend/config/JwtAuthenticationFilter.java @@ -36,7 +36,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { } @Override - protected void doFilterInternal( @NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @@ -60,8 +59,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { ); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticationToken); - - } } diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/services/EncryptionUtil.java b/src/main/java/com/skycrate/backend/skycrateBackend/services/EncryptionUtil.java index 8c53e1e..61b41de 100644 --- a/src/main/java/com/skycrate/backend/skycrateBackend/services/EncryptionUtil.java +++ b/src/main/java/com/skycrate/backend/skycrateBackend/services/EncryptionUtil.java @@ -1,9 +1,10 @@ package com.skycrate.backend.skycrateBackend.services; +import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil; + import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.security.*; -import java.util.Arrays; public class EncryptionUtil { private static final String RSA_ALGORITHM = "RSA"; @@ -19,36 +20,57 @@ public class EncryptionUtil { } // Encrypt data using AES (AES Key is encrypted using RSA) - public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception { - // Step 1: Generate AES Key - SecretKey aesKey = generateAESKey(); +// public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception { +// // Step 1: Generate AES Key +// SecretKey aesKey = generateAESKey(); +// +// // Encrypt data using AES +// Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); +// aesCipher.init(Cipher.ENCRYPT_MODE, aesKey); +// byte[] encryptedData = aesCipher.doFinal(data); +// +// // Encrypt the AES key with RSA +// Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); +// rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey); +// byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded()); +// +// // Step 4: Combine encrypted AES key and encrypted data into one array +// byte[] combined = new byte[4 + encryptedAesKey.length + encryptedData.length]; +// +// // First 4 bytes indicate the length of the AES encrypted key +// combined[0] = (byte) (encryptedAesKey.length >> 24); +// combined[1] = (byte) (encryptedAesKey.length >> 16); +// combined[2] = (byte) (encryptedAesKey.length >> 8); +// combined[3] = (byte) encryptedAesKey.length; +// +// // Copy AES Key and Encrypted Data into the combined array +// System.arraycopy(encryptedAesKey, 0, combined, 4, encryptedAesKey.length); +// System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length); +// +// return combined; +// } - // Encrypt data using AES + public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception { + SecretKey aesKey = RSAKeyUtil.generateAESKey(256); // Ensure 256 bits + byte[] encryptedData = encryptDataWithAES(data, aesKey); + byte[] encryptedAesKey = RSAKeyUtil.encryptAESKey(aesKey, publicKey); + return combineEncryptedData(encryptedAesKey, encryptedData); + } + + private static byte[] encryptDataWithAES(byte[] data, SecretKey aesKey) throws Exception { Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); aesCipher.init(Cipher.ENCRYPT_MODE, aesKey); - byte[] encryptedData = aesCipher.doFinal(data); + return aesCipher.doFinal(data); + } - // Encrypt the AES key with RSA - Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey); - byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded()); - - // Step 4: Combine encrypted AES key and encrypted data into one array + private static byte[] combineEncryptedData(byte[] encryptedAesKey, byte[] encryptedData) { byte[] combined = new byte[4 + encryptedAesKey.length + encryptedData.length]; - - // First 4 bytes indicate the length of the AES encrypted key - combined[0] = (byte) (encryptedAesKey.length >> 24); - combined[1] = (byte) (encryptedAesKey.length >> 16); - combined[2] = (byte) (encryptedAesKey.length >> 8); - combined[3] = (byte) encryptedAesKey.length; - - // Copy AES Key and Encrypted Data into the combined array System.arraycopy(encryptedAesKey, 0, combined, 4, encryptedAesKey.length); System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length); - return combined; } + // Decrypt data using RSA (AES Key is decrypted using RSA, then used for AES decryption) public static byte[] decrypt(byte[] encryptedCombined, PrivateKey privateKey) throws Exception { // Step 1: Extract AES Key length from the combined data @@ -77,11 +99,4 @@ public class EncryptionUtil { aesCipher.init(Cipher.DECRYPT_MODE, aesKey); return aesCipher.doFinal(encryptedData); } - - // Generate a random AES key - private static SecretKey generateAESKey() throws NoSuchAlgorithmException { - KeyGenerator keyGen = KeyGenerator.getInstance(AES_ALGORITHM); - keyGen.init(AES_KEY_SIZE); - return keyGen.generateKey(); - } } \ No newline at end of file diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/services/HDFSOperations.java b/src/main/java/com/skycrate/backend/skycrateBackend/services/HDFSOperations.java index ff48ce4..fc73dbf 100644 --- a/src/main/java/com/skycrate/backend/skycrateBackend/services/HDFSOperations.java +++ b/src/main/java/com/skycrate/backend/skycrateBackend/services/HDFSOperations.java @@ -39,82 +39,118 @@ public class HDFSOperations { this.userRepository = userRepository; } +// public void uploadFile(byte[] fileData, String hdfsPath, String uploadedFileName, String username) { +// try { +// FileSystem fs = HDFSConfig.getHDFS(); +// +// // Create an InputStream from the byte array +// ByteArrayInputStream inputStream = new ByteArrayInputStream(fileData); +// +// // Prepare the path for HDFS +// String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName; +// +// // Upload the file directly to HDFS from the InputStream +// Path hdfsFilePath = new Path(finalHdfsPath); +// FSDataOutputStream outputStream = fs.create(hdfsFilePath); +// IOUtils.copyBytes(inputStream, outputStream, 4096, true); +// +// } catch (IOException e) { +// // Handle I/O exception and log the error +// throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e); +// } catch (Exception e) { +// // Catch any other exceptions +// throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e); +// } +// } +// +// public void downloadFile(String hdfsEncPath, String localPathWithoutExt, String username) { +// try { +// FileSystem fs = HDFSConfig.getHDFS(); +// +// // Extract file name and extension +// String encFileName = new File(hdfsEncPath).getName(); +// String originalFileName = encFileName.replace(".enc", ""); +// String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1); +// +// String fullDecryptedPath = localPathWithoutExt + "/" + originalFileName; +// String encFilePath = fullDecryptedPath + ".enc"; +// String keyFilePath = fullDecryptedPath + ".key"; +// +// // Download encrypted file and AES key from HDFS +// fs.copyToLocalFile(new Path(hdfsEncPath), new Path(encFilePath)); +// fs.copyToLocalFile(new Path(hdfsEncPath.replace(".enc", ".key")), new Path(keyFilePath)); +// +// // Read the encrypted AES key +// byte[] encryptedAesKey = Files.readAllBytes(Paths.get(keyFilePath)); +// System.out.println("Length of encrypted AES key: " + encryptedAesKey.length); +// +// // Retrieve the RSA private key for the user +// User user = userRepository.findByUsername(username) +// .orElseThrow(() -> new RuntimeException("User not found")); +// PrivateKey privateKey = RSAKeyUtil.getPrivateKeyFromBytes(user.getPrivateKey()); +// +// Cipher rsaCipher = Cipher.getInstance("RSA"); +// rsaCipher.init(Cipher.DECRYPT_MODE, privateKey); +// byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey); +// +// // Ensure valid AES key length +// if (aesKeyBytes.length != 16 && aesKeyBytes.length != 24 && aesKeyBytes.length != 32) { +// throw new RuntimeException("Invalid AES key length: " + aesKeyBytes.length + " bytes"); +// } +// +// SecretKey aesKey = new SecretKeySpec(aesKeyBytes, 0, aesKeyBytes.length, "AES"); +// +// // Read the encrypted file content +// byte[] encryptedFileContent = Files.readAllBytes(Paths.get(encFilePath)); +// +// // Decrypt the file content using AES +// Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // Specify padding +// aesCipher.init(Cipher.DECRYPT_MODE, aesKey); +// byte[] decryptedFileContent = aesCipher.doFinal(encryptedFileContent); +// +// // Write the decrypted content to the original file +// Files.write(Paths.get(fullDecryptedPath + "." + fileExtension), decryptedFileContent); +// +// // Cleanup temporary files +// Files.deleteIfExists(Paths.get(encFilePath)); +// Files.deleteIfExists(Paths.get(keyFilePath)); +// +// } catch (Exception e) { +// throw new RuntimeException("Failed to download or decrypt file: " + e.getMessage(), e); +// } +// } + public void uploadFile(byte[] fileData, String hdfsPath, String uploadedFileName, String username) { try { FileSystem fs = HDFSConfig.getHDFS(); - - // Create an InputStream from the byte array ByteArrayInputStream inputStream = new ByteArrayInputStream(fileData); - - // Prepare the path for HDFS String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName; - - // Upload the file directly to HDFS from the InputStream Path hdfsFilePath = new Path(finalHdfsPath); - FSDataOutputStream outputStream = fs.create(hdfsFilePath); - IOUtils.copyBytes(inputStream, outputStream, 4096, true); - + try (FSDataOutputStream outputStream = fs.create(hdfsFilePath)) { + IOUtils.copyBytes(inputStream, outputStream, 4096, true); + } } catch (IOException e) { - // Handle I/O exception and log the error throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e); } catch (Exception e) { - // Catch any other exceptions - throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e); + throw new RuntimeException(e); } } public void downloadFile(String hdfsEncPath, String localPathWithoutExt, String username) { try { FileSystem fs = HDFSConfig.getHDFS(); - - // Extract file name and extension - String encFileName = new File(hdfsEncPath).getName(); - String originalFileName = encFileName.replace(".enc", ""); - String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1); - - String fullDecryptedPath = localPathWithoutExt + "/" + originalFileName; - String encFilePath = fullDecryptedPath + ".enc"; - String keyFilePath = fullDecryptedPath + ".key"; - - // Download encrypted file and AES key from HDFS + String encFilePath = localPathWithoutExt + ".enc"; fs.copyToLocalFile(new Path(hdfsEncPath), new Path(encFilePath)); - fs.copyToLocalFile(new Path(hdfsEncPath.replace(".enc", ".key")), new Path(keyFilePath)); - // Read the encrypted AES key - byte[] encryptedAesKey = Files.readAllBytes(Paths.get(keyFilePath)); - System.out.println("Length of encrypted AES key: " + encryptedAesKey.length); - - // Retrieve the RSA private key for the user User user = userRepository.findByUsername(username) .orElseThrow(() -> new RuntimeException("User not found")); PrivateKey privateKey = RSAKeyUtil.getPrivateKeyFromBytes(user.getPrivateKey()); - Cipher rsaCipher = Cipher.getInstance("RSA"); - rsaCipher.init(Cipher.DECRYPT_MODE, privateKey); - byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey); - - // Ensure valid AES key length - if (aesKeyBytes.length != 16 && aesKeyBytes.length != 24 && aesKeyBytes.length != 32) { - throw new RuntimeException("Invalid AES key length: " + aesKeyBytes.length + " bytes"); - } - - SecretKey aesKey = new SecretKeySpec(aesKeyBytes, 0, aesKeyBytes.length, "AES"); - - // Read the encrypted file content byte[] encryptedFileContent = Files.readAllBytes(Paths.get(encFilePath)); + byte[] decryptedFileContent = RSAKeyUtil.decrypt(encryptedFileContent, privateKey); - // Decrypt the file content using AES - Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // Specify padding - aesCipher.init(Cipher.DECRYPT_MODE, aesKey); - byte[] decryptedFileContent = aesCipher.doFinal(encryptedFileContent); - - // Write the decrypted content to the original file - Files.write(Paths.get(fullDecryptedPath + "." + fileExtension), decryptedFileContent); - - // Cleanup temporary files + Files.write(Paths.get(localPathWithoutExt), decryptedFileContent); Files.deleteIfExists(Paths.get(encFilePath)); - Files.deleteIfExists(Paths.get(keyFilePath)); - } catch (Exception e) { throw new RuntimeException("Failed to download or decrypt file: " + e.getMessage(), e); } diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/utils/RSAKeyUtil.java b/src/main/java/com/skycrate/backend/skycrateBackend/utils/RSAKeyUtil.java index 483d5e6..fc97d9b 100644 --- a/src/main/java/com/skycrate/backend/skycrateBackend/utils/RSAKeyUtil.java +++ b/src/main/java/com/skycrate/backend/skycrateBackend/utils/RSAKeyUtil.java @@ -52,19 +52,29 @@ public class RSAKeyUtil { keyGenerator.init(keySize); // Specify the key size return keyGenerator.generateKey(); } +// +// // Encrypt AES Key using RSA +// public static byte[] encryptAESKey(SecretKey aesKey, PublicKey publicKey) throws Exception { +// return encrypt(aesKey.getEncoded(), publicKey); // Encrypt the AES key using RSA +// } +// +// // Decrypt AES Key using RSA +// public static SecretKey decryptAESKey(byte[] encryptedAESKey, PrivateKey privateKey, int keySize) throws Exception { +// byte[] decryptedKey = decrypt(encryptedAESKey, privateKey); // Decrypt with RSA +// // Ensure that the decrypted key length matches the expected AES key size +// if (decryptedKey.length != keySize / 8) { +// throw new IllegalArgumentException("Decrypted key size does not match expected AES key size."); +// } +// return new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES"); // Convert to AES Key +// } - // Encrypt AES Key using RSA public static byte[] encryptAESKey(SecretKey aesKey, PublicKey publicKey) throws Exception { - return encrypt(aesKey.getEncoded(), publicKey); // Encrypt the AES key using RSA + return encrypt(aesKey.getEncoded(), publicKey); } - // Decrypt AES Key using RSA public static SecretKey decryptAESKey(byte[] encryptedAESKey, PrivateKey privateKey, int keySize) throws Exception { - byte[] decryptedKey = decrypt(encryptedAESKey, privateKey); // Decrypt with RSA - // Ensure that the decrypted key length matches the expected AES key size - if (decryptedKey.length != keySize / 8) { - throw new IllegalArgumentException("Decrypted key size does not match expected AES key size."); - } - return new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES"); // Convert to AES Key + byte[] decryptedKey = decrypt(encryptedAESKey, privateKey); + return new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES"); } -} \ No newline at end of file + +}