给hibernate配置文件加密 解密的方案
2009-09-21 15:03
323 查看
转自:http://www.javaeye.com/topic/70663
如何给工程中的配置文件加密 解密
之前有人问过hibernate密码问题,大家都没有给出一个具体的解决方案,所以我就看了一下代码,把我的想法和实现拿出来和大家讨论一下。
我现在的环境是spring+hibernate,但是这并不影响这个加密解密的问题,其他环境应该是略有不同,但是思路肯定是一样的。
总体思路:在工程的配置文件中填写数据库密码的密文,在应用程序使用datasource的时候解密成明文以创建连接。
步骤1
使用java的中cipher类并使用DES(对称加密算法)算法对明文进行加密
````````````````这里如何使用cipher类和DES算法的原理可以上网查找,我懒得写了,如果大家真的也怕麻烦自己去找的话我再写一个贴出来吧
修改:我随便写了一个类,大家看着改吧,我没有测试过
Java代码
public class DESUtil {
public static void main(String[] args){
try {
if(args[0].equals("-genKey")){
generateKey(args[1]);
}else{
//if (args[0].equals("-encrypt"))encrypt();
//else decrypt();
}
}catch (Exception e) {
// TODO: handle exception
}
}
public static String encrypt(String plainText, String encryptString, File keyFile)throws IOException, ClassNotFoundException,GeneralSecurityException{
ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyFile));
int mode = Cipher.ENCRYPT_MODE;
Key key = (Key)keyIn.readObject();
keyIn.close();
InputStream in = new FileInputStream(plainText);
OutputStream out = new FileOutputStream(encryptString);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(mode, key);
doEncryptAndDecrypt(in, out, cipher);
String result = out.toString();
System.out.print(result);
in.close();
out.close();
return result;
}
public static String decrypt(String encryptString, String plainText, File keyFile)throws IOException, ClassNotFoundException,GeneralSecurityException{
ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyFile));
int mode = Cipher.DECRYPT_MODE;
Key key = (Key)keyIn.readObject();
keyIn.close();
InputStream in = new FileInputStream(encryptString);
OutputStream out = new FileOutputStream(plainText);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(mode, key);
doEncryptAndDecrypt(in, out, cipher);
String result = out.toString();
System.out.print(result);
in.close();
out.close();
return result;
}
public static void doEncryptAndDecrypt(InputStream in, OutputStream out, Cipher cipher)throws IOException, GeneralSecurityException{
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
int inLength = 0;
boolean more = true;
while(more){
inLength = in.read(inBytes);
if(inLength == blockSize){
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes,0,outLength);
}
else more = false;
}
if(inLength>0) outBytes = cipher.doFinal(inBytes, 0, inLength);
else outBytes = cipher.doFinal();
out.write(outBytes);
}
public static void generateKey(String path) throws Exception{
KeyGenerator keygen = KeyGenerator.getInstance("DES");
SecureRandom random = new SecureRandom();
keygen.init(random);
SecretKey key = keygen.generateKey();
ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(path));
out.writeObject(key);
out.close();
}
}
通过以上的encrypt方法得到一个密码的密文(一般的密码是明文,作为参数传进去可以得到对应的密文),比如说21sadf25
步骤2
将加密后的密文添加到配置文件中
Java代码
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.gjt.mm.mysql.Driver"/>
<property name="url" value="jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true"/>
<property name="username" value="root"/>
<property name="password" value="21sadf25"/>
<property name="maxActive" value="100"/>
<property name="whenExhaustedAction" value="1"/>
<property name="maxWait" value="120000"/>
<property name="maxIdle" value="30"/>
<property name="defaultAutoCommit" value="true"/>
</bean>
步骤3
继承spring的LocalSessionFactoryBean类,override其setDataSource方法,将dataSource的password取出,解密后再赋值。
为什么要这么做呢,因为datasource是localsessionFactoryBean的一个属性,在注入dataSource时将其密码解密是比较恰当的。所以选择这个setDataSource方法进行override。假设我们使用的dbcp连接池
代码如下:(类名是AhuaXuanLocalSessionFactoryBean)
Java代码
public void setDataSource(DataSource dataSource) {
String password = (BasicDataSource)dataSource.getPassword();
//通过cipher类进行解密
String decryPassword = DESUtil.decrypt(password);
dataSource.setPassword(decryPassword);
this.dataSource = dataSource;
}
配置如下:
Java代码
<bean id="sessionFactory" class="org.springframework.orm.hibernate.AhuaXuanLocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
之前robbin说的DataSourceFactoryBean那个类我在spring1.2.8中没有找到,但是我觉得改造LocalSessionFactoryBean也不错
这样就完成了一个我们的目标,以上代码是随便写的,没有经过测试,有兴趣的同学可以试一下
补充:此方式我测试过,可行。
---------------------------------------------分割线----------------------------------------------------------------
最后的解决方案实际上我是直接在spring源码里改了LocalSessionFactoryBean.java,重新打包。
如何给工程中的配置文件加密 解密
之前有人问过hibernate密码问题,大家都没有给出一个具体的解决方案,所以我就看了一下代码,把我的想法和实现拿出来和大家讨论一下。
我现在的环境是spring+hibernate,但是这并不影响这个加密解密的问题,其他环境应该是略有不同,但是思路肯定是一样的。
总体思路:在工程的配置文件中填写数据库密码的密文,在应用程序使用datasource的时候解密成明文以创建连接。
步骤1
使用java的中cipher类并使用DES(对称加密算法)算法对明文进行加密
````````````````这里如何使用cipher类和DES算法的原理可以上网查找,我懒得写了,如果大家真的也怕麻烦自己去找的话我再写一个贴出来吧
修改:我随便写了一个类,大家看着改吧,我没有测试过
Java代码
public class DESUtil {
public static void main(String[] args){
try {
if(args[0].equals("-genKey")){
generateKey(args[1]);
}else{
//if (args[0].equals("-encrypt"))encrypt();
//else decrypt();
}
}catch (Exception e) {
// TODO: handle exception
}
}
public static String encrypt(String plainText, String encryptString, File keyFile)throws IOException, ClassNotFoundException,GeneralSecurityException{
ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyFile));
int mode = Cipher.ENCRYPT_MODE;
Key key = (Key)keyIn.readObject();
keyIn.close();
InputStream in = new FileInputStream(plainText);
OutputStream out = new FileOutputStream(encryptString);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(mode, key);
doEncryptAndDecrypt(in, out, cipher);
String result = out.toString();
System.out.print(result);
in.close();
out.close();
return result;
}
public static String decrypt(String encryptString, String plainText, File keyFile)throws IOException, ClassNotFoundException,GeneralSecurityException{
ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyFile));
int mode = Cipher.DECRYPT_MODE;
Key key = (Key)keyIn.readObject();
keyIn.close();
InputStream in = new FileInputStream(encryptString);
OutputStream out = new FileOutputStream(plainText);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(mode, key);
doEncryptAndDecrypt(in, out, cipher);
String result = out.toString();
System.out.print(result);
in.close();
out.close();
return result;
}
public static void doEncryptAndDecrypt(InputStream in, OutputStream out, Cipher cipher)throws IOException, GeneralSecurityException{
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
int inLength = 0;
boolean more = true;
while(more){
inLength = in.read(inBytes);
if(inLength == blockSize){
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes,0,outLength);
}
else more = false;
}
if(inLength>0) outBytes = cipher.doFinal(inBytes, 0, inLength);
else outBytes = cipher.doFinal();
out.write(outBytes);
}
public static void generateKey(String path) throws Exception{
KeyGenerator keygen = KeyGenerator.getInstance("DES");
SecureRandom random = new SecureRandom();
keygen.init(random);
SecretKey key = keygen.generateKey();
ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(path));
out.writeObject(key);
out.close();
}
}
public class DESUtil { public static void main(String[] args){ try { if(args[0].equals("-genKey")){ generateKey(args[1]); }else{ //if (args[0].equals("-encrypt"))encrypt(); //else decrypt(); } }catch (Exception e) { // TODO: handle exception } } public static String encrypt(String plainText, String encryptString, File keyFile)throws IOException, ClassNotFoundException,GeneralSecurityException{ ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyFile)); int mode = Cipher.ENCRYPT_MODE; Key key = (Key)keyIn.readObject(); keyIn.close(); InputStream in = new FileInputStream(plainText); OutputStream out = new FileOutputStream(encryptString); Cipher cipher = Cipher.getInstance("DES"); cipher.init(mode, key); doEncryptAndDecrypt(in, out, cipher); String result = out.toString(); System.out.print(result); in.close(); out.close(); return result; } public static String decrypt(String encryptString, String plainText, File keyFile)throws IOException, ClassNotFoundException,GeneralSecurityException{ ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyFile)); int mode = Cipher.DECRYPT_MODE; Key key = (Key)keyIn.readObject(); keyIn.close(); InputStream in = new FileInputStream(encryptString); OutputStream out = new FileOutputStream(plainText); Cipher cipher = Cipher.getInstance("DES"); cipher.init(mode, key); doEncryptAndDecrypt(in, out, cipher); String result = out.toString(); System.out.print(result); in.close(); out.close(); return result; } public static void doEncryptAndDecrypt(InputStream in, OutputStream out, Cipher cipher)throws IOException, GeneralSecurityException{ int blockSize = cipher.getBlockSize(); int outputSize = cipher.getOutputSize(blockSize); byte[] inBytes = new byte[blockSize]; byte[] outBytes = new byte[outputSize]; int inLength = 0; boolean more = true; while(more){ inLength = in.read(inBytes); if(inLength == blockSize){ int outLength = cipher.update(inBytes, 0, blockSize, outBytes); out.write(outBytes,0,outLength); } else more = false; } if(inLength>0) outBytes = cipher.doFinal(inBytes, 0, inLength); else outBytes = cipher.doFinal(); out.write(outBytes); } public static void generateKey(String path) throws Exception{ KeyGenerator keygen = KeyGenerator.getInstance("DES"); SecureRandom random = new SecureRandom(); keygen.init(random); SecretKey key = keygen.generateKey(); ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(path)); out.writeObject(key); out.close(); } }
通过以上的encrypt方法得到一个密码的密文(一般的密码是明文,作为参数传进去可以得到对应的密文),比如说21sadf25
步骤2
将加密后的密文添加到配置文件中
Java代码
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.gjt.mm.mysql.Driver"/>
<property name="url" value="jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true"/>
<property name="username" value="root"/>
<property name="password" value="21sadf25"/>
<property name="maxActive" value="100"/>
<property name="whenExhaustedAction" value="1"/>
<property name="maxWait" value="120000"/>
<property name="maxIdle" value="30"/>
<property name="defaultAutoCommit" value="true"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="org.gjt.mm.mysql.Driver"/> <property name="url" value="jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true"/> <property name="username" value="root"/> <property name="password" value="21sadf25"/> <property name="maxActive" value="100"/> <property name="whenExhaustedAction" value="1"/> <property name="maxWait" value="120000"/> <property name="maxIdle" value="30"/> <property name="defaultAutoCommit" value="true"/> </bean>
步骤3
继承spring的LocalSessionFactoryBean类,override其setDataSource方法,将dataSource的password取出,解密后再赋值。
为什么要这么做呢,因为datasource是localsessionFactoryBean的一个属性,在注入dataSource时将其密码解密是比较恰当的。所以选择这个setDataSource方法进行override。假设我们使用的dbcp连接池
代码如下:(类名是AhuaXuanLocalSessionFactoryBean)
Java代码
public void setDataSource(DataSource dataSource) {
String password = (BasicDataSource)dataSource.getPassword();
//通过cipher类进行解密
String decryPassword = DESUtil.decrypt(password);
dataSource.setPassword(decryPassword);
this.dataSource = dataSource;
}
public void setDataSource(DataSource dataSource) { String password = (BasicDataSource)dataSource.getPassword(); //通过cipher类进行解密 String decryPassword = DESUtil.decrypt(password); dataSource.setPassword(decryPassword); this.dataSource = dataSource; }
配置如下:
Java代码
<bean id="sessionFactory" class="org.springframework.orm.hibernate.AhuaXuanLocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate.AhuaXuanLocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean>
之前robbin说的DataSourceFactoryBean那个类我在spring1.2.8中没有找到,但是我觉得改造LocalSessionFactoryBean也不错
这样就完成了一个我们的目标,以上代码是随便写的,没有经过测试,有兴趣的同学可以试一下
补充:此方式我测试过,可行。
---------------------------------------------分割线----------------------------------------------------------------
最后的解决方案实际上我是直接在spring源码里改了LocalSessionFactoryBean.java,重新打包。
相关文章推荐
- 给hibernate配置文件加密解密的方案
- web.config文件中配置节的加密与解密
- c# web.config 配置文件的加密与解密,aspnet_regiis.exe
- ASP.NET2.0中配置文件的加密与解密
- c# web.config 配置文件的加密与解密,aspnet_regiis.exe
- Spring cloud config配置文件加密解密
- ASP.NET2.0中配置文件的加密与解密
- Hibernate配置文件加密解决方案
- Web.config配置文件的加密,解密及读写操作
- ASP.NET2.0中配置文件的加密与解密
- spring jdbc配置文件进行加密解密
- JAVA,hibernate配置文件加密
- ASP.NET2.0中配置文件的加密与解密
- asp.net配置文件connectionStrings加密和解密
- JAVA DES 对配置文件加密解密
- spring jdbc配置文件加密解密
- ASP.NET2.0中配置文件的加密与解密
- Linux下grub配置文件以及加密和解密 推荐
- 配置文件加密方案——Derby嵌入式数据库的应用