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

Tomcat 10中如何避免JDBC数据源使用明文密码并实现加密解密

Tomcat 10 自定义数据源工厂实现JDBC密码加密解密操作步骤

1. 实现自定义数据源工厂与加解密工具类

加解密工具类示例

你可以选择对称加密算法(如AES、国密SM4等)实现加解密逻辑,示例采用AES算法,密钥可通过环境变量、JVM启动参数等安全方式读取,不要硬编码在代码中:

package com.yourpackage.util;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AesEncryptUtil {
    // 实际使用时不要硬编码密钥,可从系统环境变量或JVM参数获取
    private static final String KEY = System.getenv("DB_ENCRYPT_KEY");
    private static final String ALGORITHM = "AES";

    // 加密方法,用于生成密文密码
    public static String encrypt(String plainText) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encrypted = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encrypted);
    }

    // 解密方法,用于数据源工厂中解析密文
    public static String decrypt(String cipherText) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText));
        return new String(decrypted);
    }
}

自定义数据源工厂类示例

继承Tomcat JDBC连接池默认的org.apache.tomcat.jdbc.pool.DataSourceFactory,重写数据源创建逻辑,在创建连接前解密密码:

package com.yourpackage.factory;

import com.yourpackage.util.AesEncryptUtil;
import org.apache.tomcat.jdbc.pool.DataSourceFactory;
import org.apache.tomcat.jdbc.pool.PoolConfiguration;
import javax.sql.DataSource;
import java.util.Properties;

public class EncryptedDataSourceFactory extends DataSourceFactory {
    @Override
    public DataSource createDataSource(Properties properties) throws Exception {
        // 读取配置中的加密密码
        String encryptedPwd = properties.getProperty("password");
        if (encryptedPwd != null) {
            // 解密后重新设置到配置中
            String plainPwd = AesEncryptUtil.decrypt(encryptedPwd);
            properties.setProperty("password", plainPwd);
        }
        return super.createDataSource(properties);
    }

    // 如果使用PoolConfiguration参数的重载方法,也需要同步重写
    @Override
    protected DataSource createDataSource(PoolConfiguration poolConfig) throws Exception {
        String encryptedPwd = poolConfig.getPassword();
        if (encryptedPwd != null) {
            String plainPwd = AesEncryptUtil.decrypt(encryptedPwd);
            poolConfig.setPassword(plainPwd);
        }
        return super.createDataSource(poolConfig);
    }
}

如果你使用Tomcat默认的DBCP2连接池,只需将继承的父类替换为org.apache.commons.dbcp2.BasicDataSourceFactory,解密逻辑完全一致。

2. 部署类文件到Tomcat类路径

将编译后的AesEncryptUtil、EncryptedDataSourceFactory以及所有依赖的第三方加密包全部放到${TOMCAT_HOME}/lib目录下,不要放在Web应用的WEB-INF/lib中,否则Tomcat启动加载server.xml时会找不到类。

3. 修改server.xml数据源配置

在原有数据源Resource配置中新增factory属性,值为自定义工厂的全类名,password填写加密后的密文即可:

<Resource name="jdbc/YourDB"
          auth="Container"
          type="javax.sql.DataSource"
          factory="com.yourpackage.factory.EncryptedDataSourceFactory"
          driverClassName="com.mysql.cj.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8"
          username="your_db_user"
          password="这里填写AesEncryptUtil.encrypt(原始密码)生成的密文"
          maxTotal="100"
          maxIdle="30"
          maxWaitMillis="10000"/>

注意事项

  • 加密密钥必须妥善保管,不要和密文、代码存储在同一位置,推荐使用环境变量、配置中心或硬件加密模块存储
  • 配置完成后启动Tomcat,检查启动日志确认数据源初始化正常、数据库连接成功
  • 若出现ClassNotFoundException,优先检查自定义工厂类的全类名拼写是否正确、类文件是否已放入Tomcat的lib目录

内容的提问来源于stack exchange,提问作者Riddhi Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:42:03