|
@@ -1,35 +1,25 @@
|
|
|
package com.danielbohry.stocks.service;
|
|
package com.danielbohry.stocks.service;
|
|
|
|
|
|
|
|
-import com.danielbohry.stocks.repository.PortfolioEntity;
|
|
|
|
|
-import com.danielbohry.stocks.repository.PortfolioEntity.PortfolioStock;
|
|
|
|
|
|
|
+import com.danielbohry.stocks.repository.portfolio.PortfolioEntity.PortfolioStock;
|
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
-import javax.crypto.Cipher;
|
|
|
|
|
-import javax.crypto.spec.IvParameterSpec;
|
|
|
|
|
-import javax.crypto.spec.SecretKeySpec;
|
|
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
|
|
-import java.security.SecureRandom;
|
|
|
|
|
-import java.util.Base64;
|
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
|
|
|
|
@Service
|
|
@Service
|
|
|
|
|
+@AllArgsConstructor
|
|
|
public class PortfolioEncryptService {
|
|
public class PortfolioEncryptService {
|
|
|
|
|
|
|
|
- @Value("${encryption.key}")
|
|
|
|
|
- private String secret;
|
|
|
|
|
|
|
+ private final EncryptService service;
|
|
|
|
|
|
|
|
- private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
|
|
|
|
|
- private static final int IV_LENGTH = 16;
|
|
|
|
|
- private static final int AES_KEY_SIZE = 16;
|
|
|
|
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
|
|
|
|
|
|
public String encryptStocks(List<PortfolioStock> stocks) {
|
|
public String encryptStocks(List<PortfolioStock> stocks) {
|
|
|
try {
|
|
try {
|
|
|
String toEncrypt = MAPPER.writeValueAsString(stocks);
|
|
String toEncrypt = MAPPER.writeValueAsString(stocks);
|
|
|
- return encrypt(toEncrypt);
|
|
|
|
|
|
|
+ return service.encrypt(toEncrypt);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
throw new RuntimeException("Failed to encrypt stocks", e);
|
|
throw new RuntimeException("Failed to encrypt stocks", e);
|
|
|
}
|
|
}
|
|
@@ -37,7 +27,7 @@ public class PortfolioEncryptService {
|
|
|
|
|
|
|
|
public List<PortfolioStock> decryptStocks(String encrypted) {
|
|
public List<PortfolioStock> decryptStocks(String encrypted) {
|
|
|
try {
|
|
try {
|
|
|
- String data = decrypt(encrypted);
|
|
|
|
|
|
|
+ String data = service.decrypt(encrypted);
|
|
|
return MAPPER.readValue(data, new TypeReference<>() {
|
|
return MAPPER.readValue(data, new TypeReference<>() {
|
|
|
});
|
|
});
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
@@ -45,55 +35,4 @@ public class PortfolioEncryptService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public String encrypt(String data) throws Exception {
|
|
|
|
|
- SecretKeySpec key = getSecretKey();
|
|
|
|
|
-
|
|
|
|
|
- byte[] iv = new byte[IV_LENGTH];
|
|
|
|
|
- new SecureRandom().nextBytes(iv);
|
|
|
|
|
- IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
|
|
|
|
-
|
|
|
|
|
- Cipher cipher = Cipher.getInstance(ALGORITHM);
|
|
|
|
|
- cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
|
|
|
|
|
-
|
|
|
|
|
- byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
- byte[] combined = new byte[IV_LENGTH + encrypted.length];
|
|
|
|
|
- System.arraycopy(iv, 0, combined, 0, IV_LENGTH);
|
|
|
|
|
- System.arraycopy(encrypted, 0, combined, IV_LENGTH, encrypted.length);
|
|
|
|
|
-
|
|
|
|
|
- return Base64.getEncoder().encodeToString(combined);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public String decrypt(String encryptedData) throws Exception {
|
|
|
|
|
- SecretKeySpec key = getSecretKey();
|
|
|
|
|
-
|
|
|
|
|
- byte[] combined = Base64.getDecoder().decode(encryptedData);
|
|
|
|
|
- byte[] iv = new byte[IV_LENGTH];
|
|
|
|
|
- byte[] encrypted = new byte[combined.length - IV_LENGTH];
|
|
|
|
|
-
|
|
|
|
|
- System.arraycopy(combined, 0, iv, 0, IV_LENGTH);
|
|
|
|
|
- System.arraycopy(combined, IV_LENGTH, encrypted, 0, encrypted.length);
|
|
|
|
|
-
|
|
|
|
|
- Cipher cipher = Cipher.getInstance(ALGORITHM);
|
|
|
|
|
- cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
|
|
|
|
|
-
|
|
|
|
|
- byte[] decrypted = cipher.doFinal(encrypted);
|
|
|
|
|
- return new String(decrypted, StandardCharsets.UTF_8);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public boolean isEncrypted(PortfolioEntity entity) {
|
|
|
|
|
- return entity != null &&
|
|
|
|
|
- entity.getEncryptedStocks() != null &&
|
|
|
|
|
- !entity.getEncryptedStocks().isEmpty() &&
|
|
|
|
|
- (entity.getStocks() == null || entity.getStocks().isEmpty());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private SecretKeySpec getSecretKey() {
|
|
|
|
|
- byte[] keyBytes = new byte[AES_KEY_SIZE];
|
|
|
|
|
- byte[] secretBytes = secret.getBytes(StandardCharsets.UTF_8);
|
|
|
|
|
-
|
|
|
|
|
- int length = Math.min(secretBytes.length, AES_KEY_SIZE);
|
|
|
|
|
- System.arraycopy(secretBytes, 0, keyBytes, 0, length);
|
|
|
|
|
-
|
|
|
|
|
- return new SecretKeySpec(keyBytes, "AES");
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
+}
|