In production-grade software development, storing database credentials in plain text within configuration files poses a significant security risk. To mitigate this, it is standard practice to encrypt sensitive information. This article demonstrates how to leverage the Alibaba Druid connection pool to encrypt and decrypt database passwords asymmetrical.
The encryption mechanism relies on a public-private key pair:
- Encryption: Plain text password + Private Key = Encrypted Cipher
- Decryption: Encrypted Cipher + Public Key = Plain text password
Generating Keys and Encrypted Passwords
Before modifying the configuration, you must generate the key pair and the encrypted password string. The following utility class demonstrates how to use Druid's ConfigTools to handle this.
import com.alibaba.druid.filter.config.ConfigTools;
public class DruidSecurityUtil {
public static void main(String[] args) throws Exception {
// 1. Generate an RSA key pair (2048-bit recommended for production)
// The array returns: [0] = Private Key, [1] = Public Key
String[] keyPair = ConfigTools.genKeyPair(2048);
String privateKey = keyPair[0];
String publicKey = keyPair[1];
System.out.println("Private Key (Keep this safe for encryption): " + privateKey);
System.out.println("Public Key (Use in config for decryption): " + publicKey);
// 2. Encrypt the raw database password using the Private Key
String rawCredential = "MyS3cr3tP@ssw0rd";
String encryptedValue = ConfigTools.encrypt(privateKey, rawCredential);
System.out.println("Encrypted Password to place in yaml: " + encryptedValue);
// 3. (Optional) Verify decryption logic using the Public Key
String decryptedValue = ConfigTools.decrypt(publicKey, encryptedValue);
System.out.println("Verification: " + decryptedValue.equals(rawCredential));
}
}
Configuring Spring Boot with Enrcypted Credentials
Once you have the public key and the encrypted password, update the application.yml file. You must enable Druid's config filter and provide the decryption properties.
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://prod-db-server:3306/app_schema?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: db_admin_user
# Paste the encrypted string generated by the utility class here
password: L5n8kQ9zM1xV7pP2rR4sT6uY8wA0cD2eF4gH6iJ8kL0mN2oP4qR6sT8uV0wX=
druid:
# Enable the config filter to handle decryption
filter:
config:
enabled: true
# Pass the public key and enable decryption via connection properties
connection-properties:
config.decrypt: true
config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANpT6YzV8sL9kQ4lR0gH5jK7mN2oP4qR6sT8uV0wX2yZ3aB5cD8eF1gH3iJ5kL7mN9oP1qR3sT5uV7wY0zA2cCAwEAAQ==
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
Note: Ensure the config.decrypt property is set to true. If this flag is false or missing, the application will attempt to connect to the database using the encrypted string as the literal password, causing authentication failures.