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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,10 @@ public class FileMetadata {
|
||||
@Column(nullable = false)
|
||||
private byte[] iv;
|
||||
|
||||
@Lob
|
||||
@Column(nullable = false, name = "encrypted_key")
|
||||
private byte[] encryptedKey;
|
||||
|
||||
@Column(nullable = false)
|
||||
private long uploadedAt;
|
||||
|
||||
}
|
||||
@@ -38,25 +38,37 @@ public class User implements UserDetails {
|
||||
@Lob
|
||||
private byte[] privateKey;
|
||||
|
||||
@Lob
|
||||
@Column(nullable = false)
|
||||
private byte[] privateKeySalt;
|
||||
|
||||
@Lob
|
||||
@Column(nullable = false)
|
||||
private byte[] privateKeyIv;
|
||||
|
||||
@Builder
|
||||
public User(String email, String password, String username, String fullname, byte[] publicKey, byte[] privateKey) {
|
||||
public User(String email, String password, String username, String fullname,
|
||||
byte[] publicKey, byte[] privateKey,
|
||||
byte[] privateKeySalt, byte[] privateKeyIv) {
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.username = username;
|
||||
this.fullname = fullname;
|
||||
this.publicKey = publicKey;
|
||||
this.privateKey = privateKey;
|
||||
this.privateKeySalt = privateKeySalt;
|
||||
this.privateKeyIv = privateKeyIv;
|
||||
}
|
||||
|
||||
// --- UserDetails interface methods ---
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return List.of(); // Add roles/authorities if needed
|
||||
return List.of(); // No roles assigned currently
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username; // or return username if that's your login key
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,22 +77,14 @@ public class User implements UserDetails {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
public boolean isAccountNonExpired() { return true; }
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
public boolean isAccountNonLocked() { return true; }
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
public boolean isCredentialsNonExpired() { return true; }
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
public boolean isEnabled() { return true; }
|
||||
}
|
||||
+21
-3
@@ -5,6 +5,7 @@ import com.skycrate.backend.skycrateBackend.dto.LoginUserDto;
|
||||
import com.skycrate.backend.skycrateBackend.dto.RegisterUserDto;
|
||||
import com.skycrate.backend.skycrateBackend.entity.User;
|
||||
import com.skycrate.backend.skycrateBackend.repository.UserRepository;
|
||||
import com.skycrate.backend.skycrateBackend.utils.EncryptionUtil;
|
||||
import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil;
|
||||
import org.apache.hadoop.fs.FileSystem;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
@@ -13,6 +14,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@@ -32,6 +34,7 @@ public class AuthenticationService {
|
||||
}
|
||||
|
||||
public User signUp(RegisterUserDto inputUser) {
|
||||
// Generate RSA key pair
|
||||
KeyPair keyPair;
|
||||
try {
|
||||
keyPair = RSAKeyUtil.generateKeyPair();
|
||||
@@ -39,28 +42,43 @@ public class AuthenticationService {
|
||||
throw new RuntimeException("Failed to generate RSA key pair", e);
|
||||
}
|
||||
|
||||
// Encrypt private key using password-derived AES key
|
||||
byte[] salt = EncryptionUtil.generateSalt();
|
||||
byte[] iv = EncryptionUtil.generateIv();
|
||||
byte[] encryptedPrivateKey;
|
||||
try {
|
||||
SecretKey aesKey = EncryptionUtil.deriveKey(inputUser.getPassword().toCharArray(), salt);
|
||||
encryptedPrivateKey = EncryptionUtil.encrypt(keyPair.getPrivate().getEncoded(), aesKey, iv);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to encrypt private key", e);
|
||||
}
|
||||
|
||||
// Create user entity with encrypted private key, salt, and iv
|
||||
User user = User.builder()
|
||||
.fullname(inputUser.getFirstname() + " " + inputUser.getLastname())
|
||||
.username(inputUser.getUsername())
|
||||
.email(inputUser.getEmail())
|
||||
.password(passwordEncoder.encode(inputUser.getPassword()))
|
||||
.publicKey(keyPair.getPublic().getEncoded())
|
||||
.privateKey(keyPair.getPrivate().getEncoded())
|
||||
.privateKey(encryptedPrivateKey)
|
||||
.privateKeySalt(salt)
|
||||
.privateKeyIv(iv)
|
||||
.build();
|
||||
|
||||
// Save user
|
||||
User savedUser = userRepository.save(user);
|
||||
|
||||
// Create HDFS directory in root with username
|
||||
try {
|
||||
FileSystem fs = HDFSConfig.getHDFS();
|
||||
String folderName = savedUser.getUsername();
|
||||
Path userDir = new Path("/" + folderName);
|
||||
Path userDir = new Path("/" + savedUser.getUsername());
|
||||
if (!fs.exists(userDir)) {
|
||||
fs.mkdirs(userDir);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to create HDFS directory for user: " + savedUser.getUsername(), e);
|
||||
}
|
||||
|
||||
return savedUser;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,86 +2,113 @@ package com.skycrate.backend.skycrateBackend.services;
|
||||
|
||||
import com.skycrate.backend.skycrateBackend.config.HDFSConfig;
|
||||
import com.skycrate.backend.skycrateBackend.entity.FileMetadata;
|
||||
import com.skycrate.backend.skycrateBackend.entity.User;
|
||||
import com.skycrate.backend.skycrateBackend.repository.FileMetadataRepository;
|
||||
import com.skycrate.backend.skycrateBackend.repository.UserRepository;
|
||||
import com.skycrate.backend.skycrateBackend.utils.EncryptionUtil;
|
||||
import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil;
|
||||
import org.apache.hadoop.fs.FSDataInputStream;
|
||||
import org.apache.hadoop.fs.FSDataOutputStream;
|
||||
import org.apache.hadoop.fs.FileSystem;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Optional;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
@Service
|
||||
public class FileService {
|
||||
|
||||
private final FileMetadataRepository fileMetadataRepository;
|
||||
private static final Logger log = LoggerFactory.getLogger(FileService.class);
|
||||
|
||||
public FileService(FileMetadataRepository fileMetadataRepository) {
|
||||
private final FileMetadataRepository fileMetadataRepository;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public FileService(FileMetadataRepository fileMetadataRepository, UserRepository userRepository) {
|
||||
this.fileMetadataRepository = fileMetadataRepository;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
public void uploadEncryptedFile(String username, String password, byte[] fileContent, String filename) throws Exception {
|
||||
// Generate salt and IV
|
||||
byte[] salt = EncryptionUtil.generateSalt();
|
||||
public void uploadEncryptedFile(String username, byte[] fileContent, String filename) throws Exception {
|
||||
log.info("Starting upload for user={}, file={}", username, filename);
|
||||
try {
|
||||
User user = userRepository.findByUsername(username)
|
||||
.orElseThrow(() -> new RuntimeException("User not found: " + username));
|
||||
|
||||
SecretKey aesKey = EncryptionUtil.generateAESKey();
|
||||
byte[] salt = EncryptionUtil.generateSalt(); // reserved for future use
|
||||
byte[] iv = EncryptionUtil.generateIv();
|
||||
|
||||
// Derive AES key
|
||||
SecretKey key = EncryptionUtil.deriveKey(password.toCharArray(), salt);
|
||||
byte[] encryptedData = EncryptionUtil.encrypt(fileContent, aesKey, iv);
|
||||
|
||||
// Encrypt file content
|
||||
byte[] encryptedData = EncryptionUtil.encrypt(fileContent, key, iv);
|
||||
PublicKey publicKey = RSAKeyUtil.decodePublicKey(user.getPublicKey());
|
||||
byte[] encryptedAesKey = EncryptionUtil.encryptRSA(aesKey.getEncoded(), publicKey);
|
||||
|
||||
// Prepare HDFS path
|
||||
Path userDir = new Path("/" + username);
|
||||
Path filePath = new Path(userDir, filename);
|
||||
FileSystem fs = HDFSConfig.getHDFS();
|
||||
|
||||
// Ensure user directory exists
|
||||
if (!fs.exists(userDir)) {
|
||||
log.info("Creating directory in HDFS: {}", userDir);
|
||||
fs.mkdirs(userDir);
|
||||
}
|
||||
|
||||
// Write encrypted file to HDFS
|
||||
try (FSDataOutputStream outputStream = fs.create(filePath, true);
|
||||
InputStream in = new ByteArrayInputStream(encryptedData)) {
|
||||
in.transferTo(outputStream);
|
||||
log.info("Writing encrypted file to HDFS: {}", filePath);
|
||||
try (FSDataOutputStream out = fs.create(filePath, true);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(encryptedData)) {
|
||||
in.transferTo(out);
|
||||
}
|
||||
|
||||
// Save metadata
|
||||
FileMetadata metadata = FileMetadata.builder()
|
||||
.username(username)
|
||||
.filePath(filePath.toString())
|
||||
.salt(salt)
|
||||
.iv(iv)
|
||||
.encryptedKey(encryptedAesKey)
|
||||
.uploadedAt(System.currentTimeMillis())
|
||||
.build();
|
||||
|
||||
fileMetadataRepository.save(metadata);
|
||||
log.info("Upload complete: file={} for user={}", filename, username);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error during file upload for user={}, file={}: {}", username, filename, e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] downloadDecryptedFile(String username, String password, String filename) throws Exception {
|
||||
Path filePath = new Path("/" + username + "/" + filename);
|
||||
FileSystem fs = HDFSConfig.getHDFS();
|
||||
log.info("Download request: user={}, file={}", username, filename);
|
||||
try {
|
||||
User user = userRepository.findByUsername(username)
|
||||
.orElseThrow(() -> new RuntimeException("User not found: " + username));
|
||||
|
||||
Optional<FileMetadata> metadataOpt = fileMetadataRepository.findByUsernameAndFilePath(username, filePath.toString());
|
||||
if (metadataOpt.isEmpty()) {
|
||||
throw new RuntimeException("File metadata not found");
|
||||
Path filePath = new Path("/" + username + "/" + filename);
|
||||
FileMetadata metadata = fileMetadataRepository.findByUsernameAndFilePath(username, filePath.toString())
|
||||
.orElseThrow(() -> new RuntimeException("File metadata not found for: " + filePath));
|
||||
|
||||
SecretKey derivedKey = EncryptionUtil.deriveKey(password.toCharArray(), user.getPrivateKeySalt());
|
||||
byte[] decryptedPrivateKeyBytes = EncryptionUtil.decrypt(user.getPrivateKey(), derivedKey, user.getPrivateKeyIv());
|
||||
PrivateKey privateKey = RSAKeyUtil.decodePrivateKey(decryptedPrivateKeyBytes);
|
||||
|
||||
byte[] aesKeyBytes = EncryptionUtil.decryptRSA(metadata.getEncryptedKey(), privateKey);
|
||||
SecretKey aesKey = EncryptionUtil.rebuildAESKey(aesKeyBytes);
|
||||
|
||||
FileSystem fs = HDFSConfig.getHDFS();
|
||||
byte[] encryptedData;
|
||||
try (FSDataInputStream in = fs.open(filePath)) {
|
||||
encryptedData = in.readAllBytes();
|
||||
}
|
||||
|
||||
FileMetadata metadata = metadataOpt.get();
|
||||
return EncryptionUtil.decrypt(encryptedData, aesKey, metadata.getIv());
|
||||
|
||||
// Derive key
|
||||
SecretKey key = EncryptionUtil.deriveKey(password.toCharArray(), metadata.getSalt());
|
||||
|
||||
// Read file from HDFS
|
||||
byte[] encryptedData = Files.readAllBytes(
|
||||
new java.io.File(filePath.toString()).toPath()
|
||||
);
|
||||
|
||||
// Decrypt
|
||||
return EncryptionUtil.decrypt(encryptedData, key, metadata.getIv());
|
||||
} catch (Exception e) {
|
||||
log.error("Download failed for user={}, file={}: {}", username, filename, e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,21 +4,25 @@ import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.*;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class EncryptionUtil {
|
||||
|
||||
private static final int SALT_LENGTH = 16; // 128 bits
|
||||
private static final int IV_LENGTH = 16; // 128 bits for AES
|
||||
private static final int SALT_LENGTH = 16;
|
||||
private static final int IV_LENGTH = 16;
|
||||
private static final int ITERATIONS = 65536;
|
||||
private static final int KEY_LENGTH = 256; // AES-256
|
||||
private static final int KEY_LENGTH = 256;
|
||||
|
||||
private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA256";
|
||||
private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
|
||||
private static final String AES_CIPHER = "AES/CBC/PKCS5Padding";
|
||||
private static final String RSA_CIPHER = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
|
||||
|
||||
private static final SecureRandom secureRandom = new SecureRandom();
|
||||
|
||||
// ------------------------ AES ------------------------
|
||||
|
||||
public static byte[] generateSalt() {
|
||||
byte[] salt = new byte[SALT_LENGTH];
|
||||
secureRandom.nextBytes(salt);
|
||||
@@ -38,6 +42,16 @@ public class EncryptionUtil {
|
||||
return new SecretKeySpec(tmp.getEncoded(), "AES");
|
||||
}
|
||||
|
||||
public static SecretKey generateAESKey() throws Exception {
|
||||
byte[] keyBytes = new byte[KEY_LENGTH / 8]; // 256 bits
|
||||
secureRandom.nextBytes(keyBytes);
|
||||
return new SecretKeySpec(keyBytes, "AES");
|
||||
}
|
||||
|
||||
public static SecretKey rebuildAESKey(byte[] keyBytes) {
|
||||
return new SecretKeySpec(keyBytes, "AES");
|
||||
}
|
||||
|
||||
public static byte[] encrypt(byte[] plaintext, SecretKey key, byte[] iv) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(AES_CIPHER);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||
@@ -51,4 +65,30 @@ public class EncryptionUtil {
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
|
||||
return cipher.doFinal(ciphertext);
|
||||
}
|
||||
|
||||
// ------------------------ RSA ------------------------
|
||||
|
||||
public static byte[] encryptRSA(byte[] data, PublicKey publicKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(RSA_CIPHER);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
public static byte[] decryptRSA(byte[] data, PrivateKey privateKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(RSA_CIPHER);
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
// --------- Encrypt/decrypt RSA private key using AES derived from password ---------
|
||||
|
||||
public static byte[] encryptPrivateKey(PrivateKey privateKey, String password, byte[] salt, byte[] iv) throws Exception {
|
||||
SecretKey aesKey = deriveKey(password.toCharArray(), salt);
|
||||
return encrypt(privateKey.getEncoded(), aesKey, iv);
|
||||
}
|
||||
|
||||
public static byte[] decryptPrivateKey(byte[] encryptedPrivateKey, String password, byte[] salt, byte[] iv) throws Exception {
|
||||
SecretKey aesKey = deriveKey(password.toCharArray(), salt);
|
||||
return decrypt(encryptedPrivateKey, aesKey, iv);
|
||||
}
|
||||
}
|
||||
@@ -29,44 +29,38 @@ public class RSAKeyUtil {
|
||||
return keyFactory.generatePrivate(spec);
|
||||
}
|
||||
|
||||
// Shorthand decode aliases
|
||||
public static PublicKey decodePublicKey(byte[] publicKeyBytes) throws Exception {
|
||||
return getPublicKeyFromBytes(publicKeyBytes);
|
||||
}
|
||||
|
||||
public static PrivateKey decodePrivateKey(byte[] privateKeyBytes) throws Exception {
|
||||
return getPrivateKeyFromBytes(privateKeyBytes);
|
||||
}
|
||||
|
||||
// Encrypt data using RSA (with padding)
|
||||
public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // Specify padding
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
// Decrypt data using RSA (with padding)
|
||||
public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // Specify padding
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
return cipher.doFinal(encryptedData);
|
||||
}
|
||||
|
||||
// Generate AES Key (128, 192, or 256 bits)
|
||||
// AES key generation
|
||||
public static SecretKey generateAESKey(int keySize) throws NoSuchAlgorithmException {
|
||||
if (keySize != 128 && keySize != 192 && keySize != 256) {
|
||||
throw new IllegalArgumentException("Invalid AES key size. Must be 128, 192, or 256 bits.");
|
||||
}
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
keyGenerator.init(keySize); // Specify the key size
|
||||
keyGenerator.init(keySize);
|
||||
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
|
||||
// }
|
||||
|
||||
public static byte[] encryptAESKey(SecretKey aesKey, PublicKey publicKey) throws Exception {
|
||||
return encrypt(aesKey.getEncoded(), publicKey);
|
||||
@@ -76,5 +70,4 @@ public class RSAKeyUtil {
|
||||
byte[] decryptedKey = decrypt(encryptedAESKey, privateKey);
|
||||
return new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user