Refactor encryption system to support hybrid RSA-AES encryption per file

- Changed file upload logic to:
  - Generate random AES key per file
  - Encrypt AES key using user's RSA public key
  - Store encrypted AES key, IV, and salt in FileMetadata entity

- Changed file download logic to:
  - Decrypt AES key using user's RSA private key (encrypted with password-derived AES)
  - Use decrypted AES key and IV to decrypt file contents from HDFS

- Modified FileMetadata entity:
  - Changed `encryptedKey` to @Lob byte[] to support large encrypted AES keys

- Updated User entity:
  - Encrypted private RSA key with password-derived AES
  - Stored associated salt and IV for decryption

- Updated AuthenticationService:
  - Generate RSA keypair during sign-up
  - Encrypt and store private key with AES (salt, IV)
  - Create user folder in HDFS upon registration

- Updated FileService:
  - Rewrote upload and download logic to support hybrid encryption
  - Handled key wrapping and unwrapping securely
  - Added logging for upload/download events

- Fixed FileController upload to remove password from endpoint
  - Password now only required during download for private key decryption

- Updated EncryptionUtil and RSAKeyUtil:
  - Added RSA OAEP support and helper methods
  - Added AES key generation, encryption, decryption utilities

FILE UPLOAD AND ENCRYPTION WORKS! TESTED USING HEXDUMP.
This commit is contained in:
K
2025-07-03 16:22:41 +05:30
parent 23eda639c0
commit 4af5aabd42
7 changed files with 190 additions and 105 deletions
@@ -4,6 +4,7 @@ import com.skycrate.backend.skycrateBackend.services.FileService;
import com.skycrate.backend.skycrateBackend.services.JwtService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -22,20 +23,19 @@ public class FileController {
}
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(
public ResponseEntity<?> uploadFile(
@RequestParam("file") MultipartFile file,
@RequestParam("password") String password,
HttpServletRequest request
) {
HttpServletRequest request) {
try {
String token = extractToken(request);
String username = jwtService.extractUsername(token);
fileService.uploadEncryptedFile(username, password, file.getBytes(), file.getOriginalFilename());
fileService.uploadEncryptedFile(username, file.getBytes(), file.getOriginalFilename());
return ResponseEntity.ok("File uploaded and encrypted successfully.");
} catch (Exception e) {
return ResponseEntity.status(500).body("File upload failed: " + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Upload failed: " + e.getMessage());
}
}