EncryptService.java 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package com.danielbohry.stocks.service;
  2. import com.danielbohry.stocks.exception.DecryptionKeyException;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.stereotype.Service;
  5. import javax.crypto.BadPaddingException;
  6. import javax.crypto.Cipher;
  7. import javax.crypto.spec.IvParameterSpec;
  8. import javax.crypto.spec.SecretKeySpec;
  9. import java.nio.charset.StandardCharsets;
  10. import java.security.SecureRandom;
  11. import java.util.Base64;
  12. @Service
  13. public class EncryptService {
  14. @Value("${encryption.key}")
  15. private String secret;
  16. private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
  17. private static final int IV_LENGTH = 16;
  18. private static final int AES_KEY_SIZE = 16;
  19. public String encrypt(String data) throws Exception {
  20. SecretKeySpec key = getSecretKey();
  21. byte[] iv = new byte[IV_LENGTH];
  22. new SecureRandom().nextBytes(iv);
  23. IvParameterSpec ivSpec = new IvParameterSpec(iv);
  24. Cipher cipher = Cipher.getInstance(ALGORITHM);
  25. cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
  26. byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
  27. byte[] combined = new byte[IV_LENGTH + encrypted.length];
  28. System.arraycopy(iv, 0, combined, 0, IV_LENGTH);
  29. System.arraycopy(encrypted, 0, combined, IV_LENGTH, encrypted.length);
  30. return Base64.getEncoder().encodeToString(combined);
  31. }
  32. public String decrypt(String encryptedData) throws Exception {
  33. try {
  34. SecretKeySpec key = getSecretKey();
  35. byte[] combined = Base64.getDecoder().decode(encryptedData);
  36. byte[] iv = new byte[IV_LENGTH];
  37. byte[] encrypted = new byte[combined.length - IV_LENGTH];
  38. System.arraycopy(combined, 0, iv, 0, IV_LENGTH);
  39. System.arraycopy(combined, IV_LENGTH, encrypted, 0, encrypted.length);
  40. Cipher cipher = Cipher.getInstance(ALGORITHM);
  41. cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
  42. byte[] decrypted = cipher.doFinal(encrypted);
  43. return new String(decrypted, StandardCharsets.UTF_8);
  44. } catch (BadPaddingException e) {
  45. throw new DecryptionKeyException("Cannot decrypt data", e);
  46. }
  47. }
  48. private SecretKeySpec getSecretKey() {
  49. byte[] keyBytes = new byte[AES_KEY_SIZE];
  50. byte[] secretBytes = secret.getBytes(StandardCharsets.UTF_8);
  51. int length = Math.min(secretBytes.length, AES_KEY_SIZE);
  52. System.arraycopy(secretBytes, 0, keyBytes, 0, length);
  53. return new SecretKeySpec(keyBytes, "AES");
  54. }
  55. }