jbpm - hibernate 的数据库加密解密的实现
1. 描述
jbpm工作流的数据库相关操作本质上是hibernate的相关操作。我们在开发部署时,系统安全验证要求对数据库的用户名、密码进行加密。这里提供了基于java的数据库加密、解密的算法实现及jbpm- hibernate的数据库加解密的实现。
一. 加密解密算法实现参考:
数据库账号的加密解密:https://blog.csdn.net/weixin_44462773/article/details/120453344
二. 加密解密源码下载链接:
https://download.csdn.net/download/weixin_44462773/24395402.
2. jbpm -hibernate 的数据库加密配置
2.1 工程引用加解密算法
下载“加密解密算法源码”,导出成jar包,引用
二. 加密解密源码下载链接:
https://download.csdn.net/download/weixin_44462773/24395402.
2.2 生成加密的字符串
写一个main函数,调用加密算法,生成以数据库名为key的用户名、密码的加密字符串
public static void main(String[] args) {
String databaseName = "jbpmdb";
String username = "root";
String passward = "1234";
System.out.println(username+" :"+EncryptAndDecryptStr.encryptStr(databaseName, username));
System.out.println(passward+" :"+EncryptAndDecryptStr.encryptStr(databaseName, passward));
}
结果输出示例:
2.3 配置文件
将生成的加密字符串,配置到jbpm.hibernate.cfg.xml
配置文件中的“ 数据库连接配置”中,配置文件示例如下:
<?xml version="1.0" encoding="utf-8"?>
<!-- Hibernate主配置文件 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一个session-factory节点代表一个数据库 -->
<session-factory>
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jbpmdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8</property>
<property name="hibernate.connection.username">evw5EOZW7lI=</property>
<property name="hibernate.connection.password">yhe5XTz2RLs=</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">false</property>
<!-- 2.3 自动建表 :如果表不存在就创建; 表存在就不创建; -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 使用c3p0的指定 -->
<property name="hibernate.connection.provider_class">com.math.jbpm.MyC3P0ConnectionProvider</property>
<!--使用c3p0的最小数据连接数量-->
<property name="hibernate.c3p0.min_size">5</property>
<!-- 使用c3p0维护的最大连接数量 -->
<property name="hibernate.c3p0.min_size">20</property>
<!-- 使用c3p0的超时限制 -->
<property name="hibernate.c3p0.timeout">300</property>
<!-- 使用c3p0维护的最大statement数量 -->
<property name="hibernate.c3p0.max_statements">50</property>
<!-- 使用c3p0生效的空闲时间 -->
<property name="hibernate.c3p0.idle_test_period">3000</property>
<!--3. 加载所有映射-->
<mapping resource="jbpm.repository.hbm.xml" />
<mapping resource="jbpm.execution.hbm.xml" />
<mapping resource="jbpm.history.hbm.xml" />
<mapping resource="jbpm.task.hbm.xml" />
<mapping resource="jbpm.identity.hbm.xml" />
<!-- 自定义对象的变量定义文件引入 -->
<!-- <mapping resource="variable/power_device.hbm.xml" /> -->
<!-- <mapping resource="variable/user.hbm.xml" /> -->
</session-factory>
</hibernate-configuration>
2.4 重写数据库连接供应器
- 在上面的
jbpm.hibernate.cfg.xml
配置文件中,指定“数据库连接供应器”的实现类:
<property name="hibernate.connection.provider_class">com.math.jbpm.MyC3P0ConnectionProvider</property>
- 连接供应器实现:
/**
* A connection provider that uses a C3P0 connection pool. Hibernate will use
* this by default if the <tt>hibernate.c3p0.*</tt> properties are set.
* @author various people
* @see ConnectionProvider
*/
public class MyC3P0ConnectionProvider implements ConnectionProvider {
private static final Log log = LogFactory.getLog(MyC3P0ConnectionProvider.class);
private DataSource ds;
private Integer isolation;
private static DatabaseEnDeCryptInterface databaseInter;
static{
databaseInter = new DatabaseEnDeCryptInterface() {
@Override
public String getEncryptUserName(String arg0, String arg1) {
return EncryptAndDecryptStr.encryptStr(arg0, arg1);
}
@Override
public String getEncryptPassward(String arg0, String arg1) {
return EncryptAndDecryptStr.encryptStr(arg0, arg1);
}
@Override
public String getDecryptUserName(String arg0, String arg1) {
return EncryptAndDecryptStr.decryptStr(arg0, arg1);
}
@Override
public String getDecryptPassward(String arg0, String arg1) {
return EncryptAndDecryptStr.decryptStr(arg0, arg1);
}
};
}
public Connection getConnection() throws SQLException {
final Connection c = ds.getConnection();
if (isolation != null)
c.setTransactionIsolation(isolation.intValue());
if (c.getAutoCommit())
c.setAutoCommit(false);
return c;
}
public void closeConnection(Connection conn) throws SQLException {
conn.close();
}
public void configure(Properties props) throws HibernateException {
String jdbcDriverClass = props.getProperty(Environment.DRIVER);
if(jdbcDriverClass == null) {
log.warn("No JDBC Driver class was specified by property " + Environment.DRIVER);
}else {
try {
Class.forName(jdbcDriverClass);
} catch (ClassNotFoundException cnfe) {
String msg = "JDBC Driver class not found: " + jdbcDriverClass;
log.fatal(msg);
throw new HibernateException(msg);
}
}
Properties connectionProps = ConnectionProviderFactory.getConnectionProperties(props);
try {
int minPoolSize = PropertiesHelper.getInt(Environment.C3P0_MIN_SIZE, props, 1);
int maxPoolSize = PropertiesHelper.getInt(Environment.C3P0_MAX_SIZE, props, 100);
int maxIdleTime = PropertiesHelper.getInt(Environment.C3P0_TIMEOUT, props, 0);
int maxStatements = PropertiesHelper.getInt(Environment.C3P0_MAX_STATEMENTS, props, 0);
int acquireIncrement = PropertiesHelper.getInt(Environment.C3P0_ACQUIRE_INCREMENT, props, 1);
int idleTestPeriod = PropertiesHelper.getInt(Environment.C3P0_IDLE_TEST_PERIOD, props, 0);
PoolConfig pcfg = new PoolConfig();
pcfg.setInitialPoolSize(minPoolSize);
pcfg.setMinPoolSize(minPoolSize);
pcfg.setMaxPoolSize(maxPoolSize);
pcfg.setAcquireIncrement(acquireIncrement);
pcfg.setMaxIdleTime(maxIdleTime);
pcfg.setMaxStatements(maxStatements);
pcfg.setIdleConnectionTestPeriod(idleTestPeriod);
String jdbcUrl = props.getProperty(Environment.URL);
connectionProps.setProperty("user", databaseInter.getDecryptUserName(getDatabaseNameFromURL(jdbcUrl), props.getProperty(Environment.USER)));
connectionProps.setProperty("password",databaseInter.getDecryptPassward(getDatabaseNameFromURL(jdbcUrl), props.getProperty(Environment.PASS)));
DataSource unpooled = DataSources.unpooledDataSource(jdbcUrl, connectionProps);
ds = DataSources.pooledDataSource(unpooled, pcfg);
} catch (Exception e) {
log.fatal("could not instantiate C3P0 connection pool", e);
throw new HibernateException("Could not instantiate C3P0 connection pool", e);
}
String i = props.getProperty(Environment.ISOLATION);
if (i == null) {
isolation = null;
} else {
isolation = new Integer(i);
log.info("JDBC isolation level: " + Environment.isolationLevelToString(isolation.intValue()));
}
}
/**
* 从url中获取数据库名称:
* jdbc:mysql://127.0.0.1:3306/powflow_dstrnet_anhui?useSSL=true&useUnicode=true&characterEncoding=UTF-8
* @param url
* @return
*/
public String getDatabaseNameFromURL(String url){
if(url != null && !"".equals(url)){
url = url.substring(0,url.lastIndexOf("?"));
String[] ss = url.split("/");
url = ss[ss.length-1];
}
return url;
}
public void close() {
try {
DataSources.destroy(ds);
} catch (SQLException sqle) {
log.warn("could not destroy C3P0 connection pool", sqle);
}
}
@Override
public boolean supportsAggressiveRelease() {
return false;
}
}
上一章: 数据库账号的加密解密.