Implemented Encryption and Decryption Needed to be as saved Response

This commit is contained in:
2025-04-18 00:28:45 +05:30
parent 5cd396951d
commit 03bdb5d898
4 changed files with 151 additions and 93 deletions
@@ -36,7 +36,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
} }
@Override @Override
protected void doFilterInternal( protected void doFilterInternal(
@NonNull HttpServletRequest request, @NonNull HttpServletRequest request,
@NonNull HttpServletResponse response, @NonNull HttpServletResponse response,
@@ -60,8 +59,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
); );
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authenticationToken);
} }
} }
@@ -1,9 +1,10 @@
package com.skycrate.backend.skycrateBackend.services; package com.skycrate.backend.skycrateBackend.services;
import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil;
import javax.crypto.*; import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.security.*; import java.security.*;
import java.util.Arrays;
public class EncryptionUtil { public class EncryptionUtil {
private static final String RSA_ALGORITHM = "RSA"; private static final String RSA_ALGORITHM = "RSA";
@@ -19,36 +20,57 @@ public class EncryptionUtil {
} }
// Encrypt data using AES (AES Key is encrypted using RSA) // Encrypt data using AES (AES Key is encrypted using RSA)
public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception { // public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
// Step 1: Generate AES Key // // Step 1: Generate AES Key
SecretKey aesKey = generateAESKey(); // 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"); Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey); aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encryptedData = aesCipher.doFinal(data); return aesCipher.doFinal(data);
}
// Encrypt the AES key with RSA private static byte[] combineEncryptedData(byte[] encryptedAesKey, byte[] encryptedData) {
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]; 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(encryptedAesKey, 0, combined, 4, encryptedAesKey.length);
System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length); System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length);
return combined; return combined;
} }
// Decrypt data using RSA (AES Key is decrypted using RSA, then used for AES decryption) // 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 { public static byte[] decrypt(byte[] encryptedCombined, PrivateKey privateKey) throws Exception {
// Step 1: Extract AES Key length from the combined data // Step 1: Extract AES Key length from the combined data
@@ -77,11 +99,4 @@ public class EncryptionUtil {
aesCipher.init(Cipher.DECRYPT_MODE, aesKey); aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
return aesCipher.doFinal(encryptedData); 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();
}
} }
@@ -39,82 +39,118 @@ public class HDFSOperations {
this.userRepository = userRepository; 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) { public void uploadFile(byte[] fileData, String hdfsPath, String uploadedFileName, String username) {
try { try {
FileSystem fs = HDFSConfig.getHDFS(); FileSystem fs = HDFSConfig.getHDFS();
// Create an InputStream from the byte array
ByteArrayInputStream inputStream = new ByteArrayInputStream(fileData); ByteArrayInputStream inputStream = new ByteArrayInputStream(fileData);
// Prepare the path for HDFS
String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName; String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName;
// Upload the file directly to HDFS from the InputStream
Path hdfsFilePath = new Path(finalHdfsPath); Path hdfsFilePath = new Path(finalHdfsPath);
FSDataOutputStream outputStream = fs.create(hdfsFilePath); try (FSDataOutputStream outputStream = fs.create(hdfsFilePath)) {
IOUtils.copyBytes(inputStream, outputStream, 4096, true); IOUtils.copyBytes(inputStream, outputStream, 4096, true);
}
} catch (IOException e) { } catch (IOException e) {
// Handle I/O exception and log the error
throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e); throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e);
} catch (Exception e) { } catch (Exception e) {
// Catch any other exceptions throw new RuntimeException(e);
throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e);
} }
} }
public void downloadFile(String hdfsEncPath, String localPathWithoutExt, String username) { public void downloadFile(String hdfsEncPath, String localPathWithoutExt, String username) {
try { try {
FileSystem fs = HDFSConfig.getHDFS(); FileSystem fs = HDFSConfig.getHDFS();
String encFilePath = localPathWithoutExt + ".enc";
// 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), 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) User user = userRepository.findByUsername(username)
.orElseThrow(() -> new RuntimeException("User not found")); .orElseThrow(() -> new RuntimeException("User not found"));
PrivateKey privateKey = RSAKeyUtil.getPrivateKeyFromBytes(user.getPrivateKey()); 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[] encryptedFileContent = Files.readAllBytes(Paths.get(encFilePath));
byte[] decryptedFileContent = RSAKeyUtil.decrypt(encryptedFileContent, privateKey);
// Decrypt the file content using AES Files.write(Paths.get(localPathWithoutExt), decryptedFileContent);
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(encFilePath));
Files.deleteIfExists(Paths.get(keyFilePath));
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Failed to download or decrypt file: " + e.getMessage(), e); throw new RuntimeException("Failed to download or decrypt file: " + e.getMessage(), e);
} }
@@ -52,19 +52,29 @@ public class RSAKeyUtil {
keyGenerator.init(keySize); // Specify the key size keyGenerator.init(keySize); // Specify the key size
return keyGenerator.generateKey(); 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 { 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 { public static SecretKey decryptAESKey(byte[] encryptedAESKey, PrivateKey privateKey, int keySize) throws Exception {
byte[] decryptedKey = decrypt(encryptedAESKey, privateKey); // Decrypt with RSA byte[] decryptedKey = decrypt(encryptedAESKey, privateKey);
// Ensure that the decrypted key length matches the expected AES key size return new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES");
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
} }
} }