You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在aes_encrypt中传入自定义密钥?Spring Boot密钥安全存储方案

How to Store AES Key Outside Java Code for Hibernate @ColumnTransformer

Great question—hardcoding encryption keys directly in your Java classes is a major security red flag, since decompiling the class file would expose them instantly. Let’s walk through several secure, practical solutions for your Spring Boot + JPA/Hibernate + MySQL stack:

1. Use Spring Boot Configuration Files + SpEL Expressions

The simplest approach is to move your key to a Spring configuration file (like application.properties or application.yml) and reference it using Spring Expression Language (SpEL) in your @ColumnTransformer annotation.

Step 1: Add the key to your config file

In application.properties:

# Store your key here (make sure this file is NOT committed to version control!)
mysql.encryption.key=YourStrongUniqueKey123!

Step 2: Reference the key in @ColumnTransformer

Update your entity field to use the SpEL placeholder:

@ColumnTransformer(
    write = "aes_encrypt(sensitive_column, '${mysql.encryption.key}')",
    read = "aes_decrypt(sensitive_column, '${mysql.encryption.key}')"
)
@Column(name = "sensitive_column")
private String sensitiveData;

Spring will automatically replace ${mysql.encryption.key} with the value from your config file at runtime.

2. Use Environment Variables (More Secure Than Config Files)

To avoid storing keys in plaintext config files entirely, use environment variables. This keeps keys out of your codebase and server files.

Step 1: Set the environment variable

On Linux/macOS:

export MYSQL_ENCRYPT_KEY="YourEvenStrongerKey!"

On Windows (Command Prompt):

set MYSQL_ENCRYPT_KEY=YourEvenStrongerKey!

Step 2: Reference the variable in your config file

In application.properties:

mysql.encryption.key=${MYSQL_ENCRYPT_KEY}

Your @ColumnTransformer annotation stays exactly the same as in the first method.

3. Encrypt Config File Values with Jasypt

If you must keep keys in config files, encrypt them using Jasypt so even if the config file leaks, the key remains unreadable.

Step 1: Add Jasypt dependency

Include the Jasypt Spring Boot starter in your pom.xml:

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>

Step 2: Encrypt your key

Use Jasypt’s command-line tool to generate an encrypted version of your key:

java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="YourSecretKey" password="MasterEncryptionPassword" algorithm=PBEWithMD5AndDES

Replace MasterEncryptionPassword with a secure master password (this should be stored in an environment variable, not a config file).

Step 3: Configure encrypted key in application.properties

# Master password from environment variable
jasypt.encryptor.password=${JASYPT_MASTER_PASSWORD}
# Encrypted key wrapped in ENC()
mysql.encryption.key=ENC(your-encrypted-key-string-here)

Spring will automatically decrypt the key at runtime using the master password.

4. Custom Hibernate Attribute Converter (Alternative to @ColumnTransformer)

If you want more control over encryption logic (or prefer encrypting/decrypting in Java rather than MySQL), use a custom AttributeConverter. This lets you inject the key directly into the converter via Spring.

Example Converter Class

@Converter(autoApply = false)
public class AesAttributeConverter implements AttributeConverter<String, String> {

    private final String encryptionKey;

    // Inject key from Spring environment
    public AesAttributeConverter(@Value("${mysql.encryption.key}") String encryptionKey) {
        this.encryptionKey = encryptionKey;
    }

    @Override
    public String convertToDatabaseColumn(String attribute) {
        // Implement AES encryption logic here
        try {
            Cipher cipher = Cipher.getInstance("AES");
            SecretKeySpec keySpec = new SecretKeySpec(encryptionKey.getBytes(StandardCharsets.UTF_8), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            return Base64.getEncoder().encodeToString(cipher.doFinal(attribute.getBytes(StandardCharsets.UTF_8)));
        } catch (Exception e) {
            throw new RuntimeException("Failed to encrypt data", e);
        }
    }

    @Override
    public String convertToEntityAttribute(String dbData) {
        // Implement AES decryption logic here
        try {
            Cipher cipher = Cipher.getInstance("AES");
            SecretKeySpec keySpec = new SecretKeySpec(encryptionKey.getBytes(StandardCharsets.UTF_8), "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            return new String(cipher.doFinal(Base64.getDecoder().decode(dbData)), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("Failed to decrypt data", e);
        }
    }
}

Use the Converter in Your Entity

@Convert(converter = AesAttributeConverter.class)
@Column(name = "sensitive_column")
private String sensitiveData;

Critical Security Best Practices

  • Never commit keys to version control: Add application.properties/application.yml to your .gitignore file.
  • Use a secrets manager in production: For enterprise-grade security, use tools like HashiCorp Vault, AWS KMS, or Azure Key Vault to store and retrieve keys dynamically.
  • Rotate keys regularly: Set up a process to rotate encryption keys periodically to minimize risk if a key is compromised.
  • Encrypt database connections: Always use SSL/TLS for your MySQL connection to prevent key exposure during transit.

内容的提问来源于stack exchange,提问作者Abhijeet Saxena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:43:46