给hibernate配置文件加密 解密的方案

 

引用:http://www.iteye.com/topic/70663   (先转过来,有需要的时候参考)

 

如何给工程中的配置文件加密 解密
之前有人问过hibernate密码问题,大家都没有给出一个具体的解决方案,所以我就看了一下代码,把我的想法和实现拿出来和大家讨论一下。

我现在的环境是spring+hibernate,但是这并不影响这个加密解密的问题,其他环境应该是略有不同,但是思路肯定是一样的。

总体思路:在工程的配置文件中填写数据库密码的密文,在应用程序使用datasource的时候解密成明文以创建连接。
步骤1
使用java的中cipher类并使用DES(对称加密算法)算法对明文进行加密
````````````````这里如何使用cipher类和DES算法的原理可以上网查找,我懒得写了,如果大家真的也怕麻烦自己去找的话我再写一个贴出来吧

修改:我随便写了一个类,大家看着改吧,我没有测试过

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
将加密后的密文添加到配置文件中

<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)

public void setDataSource(DataSource dataSource) {   
String password = (BasicDataSource)dataSource.getPassword();   
//通过cipher类进行解密   
String decryPassword = DESUtil.decrypt(password);   
dataSource.setPassword(decryPassword);   
        this.dataSource = dataSource;   
    }  

配置如下:

<bean id="sessionFactory" class="org.springframework.orm.hibernate.AhuaXuanLocalSessionFactoryBean">   
                    <property name="dataSource">   
            <ref bean="dataSource"/>   
        </property>   
</bean>  

之前robbin说的DataSourceFactoryBean那个类我在spring1.2.8中没有找到,但是我觉得改造LocalSessionFactoryBean也不错

这样就完成了一个我们的目标,以上代码是随便写的,没有经过测试,有兴趣的同学可以试一下

 

 

纯转载收藏,有机会在深入,目前还没有在此基础上实现过!!!

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值