欢迎投稿

今日深度:

加密jdbc连接以及表敏感字段,加密jdbc字段

加密jdbc连接以及表敏感字段,加密jdbc字段


本文使用Jasypt与Hibernate集成,透明加密个人数据、私有信息等重要数据,避免其他拥有权限的人可以使用终端访问数据库以及关键表内容。大致思路是:先用jasypt加密连接数据库的url、username、password、driverClass,自定义DruidConnectionProvider解密这些属性,然后连接数据库;实体entity字段的加密是通过自定义Hibernate UserType实现。

前言

开发环境:Eclipse+JDK8+Hibernate5

参考资料:http://www.jasypt.org/hibernate.html

demo下载:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=478

加密url、用户名、密码、驱动类

public void generateJDBCString() {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setAlgorithm(ParamEncryptor.ALGORITHM);
        encryptor.setProvider(new BouncyCastleProvider());// none-JCE
        encryptor.setPassword(ParamEncryptor.ALGORITHM_PASSWORD);
 
        String driverClass = "org.mariadb.jdbc.Driver";
        String url = "jdbc:mariadb://localhost:3306/mysql";
        String username = "test";
        String pwd = "123456";
         
        String encryptDriverClass = encryptor.encrypt(driverClass);
        String encryptUrl = encryptor.encrypt(url);
        String encryptUsername = encryptor.encrypt(username);
        String encryptPwd = encryptor.encrypt(pwd);
        System.out.println("driver class: "+encryptDriverClass);
        System.out.println("url: "+encryptUrl);
        System.out.println("username: "+encryptUsername);
        System.out.println("pwd: "+encryptPwd);
    }
自定义数据库连接池连接提供者DruidConnectionProvider,解密url、用户名、密码、驱动类

public class EncryptedDruidConnectionProvider extends DruidConnectionProvider {
 
    /**
     * 
     */
    private static final long serialVersionUID = -409669485957486646L;
     
    public EncryptedDruidConnectionProvider() {
        super();
    }
 
    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public void configure(Map props) {
 
        final String encryptorRegisteredName = (String) props.get("hibernate.connection.encryptor_registered_name");
 
        final HibernatePBEEncryptorRegistry encryptorRegistry = HibernatePBEEncryptorRegistry.getInstance();
        final PBEStringEncryptor encryptor = encryptorRegistry.getPBEStringEncryptor(encryptorRegisteredName);
 
        if (encryptor == null) {
            throw new EncryptionInitializationException("No string encryptor registered for hibernate " + "with name \"" + encryptorRegisteredName + "\"");
        }
 
        // Get the original values, which may be encrypted
        final String driver = (String) props.get(DruidDataSourceFactory.PROP_DRIVERCLASSNAME);
        final String url = (String) props.get(DruidDataSourceFactory.PROP_URL);
        final String user = (String) props.get(DruidDataSourceFactory.PROP_USERNAME);
        final String password = (String) props.get(DruidDataSourceFactory.PROP_PASSWORD);
 
        // Perform decryption operations as needed and store the new values
        if (PropertyValueEncryptionUtils.isEncryptedValue(driver)) {
            props.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, PropertyValueEncryptionUtils.decrypt(driver, encryptor));
        }
        if (PropertyValueEncryptionUtils.isEncryptedValue(url)) {
            props.put(DruidDataSourceFactory.PROP_URL, PropertyValueEncryptionUtils.decrypt(url, encryptor));
        }
        if (PropertyValueEncryptionUtils.isEncryptedValue(user)) {
            props.put(DruidDataSourceFactory.PROP_USERNAME, PropertyValueEncryptionUtils.decrypt(user, encryptor));
        }
        if (PropertyValueEncryptionUtils.isEncryptedValue(password)) {
            props.put(DruidDataSourceFactory.PROP_PASSWORD, PropertyValueEncryptionUtils.decrypt(password, encryptor));
        }
 
        // Let Hibernate do the rest
        super.configure(props);
    }
 
}
配置hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.encryptor_registered_name">hibernateStringEncryptor</property>
         
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.provider_class">com.wisdomdd.dataEncryption_hibernate.util.EncryptedDruidConnectionProvider</property>
        <property name="url">ENC(xZ+JDmEcwFauyvMrXhRyFloaJ3JRQ30pCGx00Y9jS8xugKy7etWhEzJXHa+37K9J)</property>
        <property name="username">ENC(uWnvfEFEOPFEaelwwiYK0Q==)</property>
        <property name="password">ENC(kRKRp1R3xeeFd510BOnwcg==)</property>
        <property name="driverClassName">ENC(N658dS3sxVcjUG8uNdJKuDjlvyUUdHwoGVUnT+vl0/k=)</property>
        <property name="hibernate.jdbc.batch_size">20</property>
        <property name="hibernate.jdbc.fetch_size">30</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize">1</property>
        <property name="minIdle">1</property>
        <property name="maxActive">20</property>
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait">60000</property>
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis">60000</property>
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis">300000</property>
        <property name="validationQuery">SELECT 'x'</property>
        <property name="testWhileIdle">true</property>
        <property name="testOnBorrow">false</property>
        <property name="testOnReturn">false</property>
        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
        <property name="poolPreparedStatements">true</property>
        <property name="maxPoolPreparedStatementPerConnectionSize">20</property>
        <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
        <property name="filters">stat</property>
        <!-- 配置注解映射类 -->
        <mapping class="com.wisdomdd.dataEncryption_hibernate.entity.Account" />
    </session-factory>
</hibernate-configuration>

使用注解映射实体,Jasypt加解密数据

首先用一个@TypeDef注解来定义加密类型,这个注解可以在持久实体类中,或者在一个单独的package-info.java文件中的@TypeDefs声明中:

@TypeDef(
    name =“encryptedString”,
    typeClass = EncryptedStringType.class,
    parameters = { 
        @Parameter(name =“encryptorRegisteredName”,value =“myHibernateStringEncryptor”)
    } )

...然后简单地将我们的属性与已经声明的类型进行映射:
 @Type(type =“encryptedString”)
    public String getAddress(){ 
        return address; 
    }

结束语

以上是部分代码,完整运行实例,请下载附件Demo。

   demo下载:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=478



www.htsjk.Com true http://www.htsjk.com/shujukunews/10015.html NewsArticle 加密jdbc连接以及表敏感字段,加密jdbc字段 本文使用Jasypt与Hibernate集成,透明加密个人数据、私有信息等重要数据,避免其他拥有权限的人可以使用终端访问数据库以及关键表内容。大...
评论暂时关闭