读取项目中properties文件中的账号密码进行加密解密

来源:互联网 发布:java获取系统时间 编辑:程序博客网 时间:2024/05/17 22:01

项目需求 :

所有认证数据,例如密码,不论是在储存、传输中都必须妥善保护,以防泄露或被未获授权修改。在安全认证中的Fortify 静态代码分析器的扫描中,如果密码明文放在文件中是肯定过不去的。

 


需求解决方案: 
下面具体结合SSH的框架的代码实现。 
1. 认证数据加密 
所有认证数据通过 3DES 加密;加解密方法如下:

Java代码 1.

import java.security.Key;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class DesEncrypt { /**  *   * 使用DES加密与解密,可对byte[],String类型进行加密与解密 密文可使用String,byte[]存储.  *   * 方法: void getKey(String strKey)从strKey的字条生成一个Key  *   * String getEncString(String strMing)对strMing进行加密,返回String密文 String  * getDesString(String strMi)对strMin进行解密,返回String明文  *   *byte[] getEncCode(byte[] byteS)byte[]型的加密 byte[] getDesCode(byte[]  * byteD)byte[]型的解密  */ Key key; /**  * 根据参数生成KEY  *   * @param strKey  */ public void getKey(String strKey) {  try {   KeyGenerator _generator = KeyGenerator.getInstance("DES");   _generator.init(new SecureRandom(strKey.getBytes()));   this.key = _generator.generateKey();   _generator = null;  } catch (Exception e) {   e.printStackTrace();  } } /**  * 加密String明文输入,String密文输出  *   * @param strMing  * @return  */ public String getEncString(String strMing) {  byte[] byteMi = null;  byte[] byteMing = null;  String strMi = "";  BASE64Encoder base64en = new BASE64Encoder();  try {   byteMing = strMing.getBytes("UTF8");   byteMi = this.getEncCode(byteMing);   strMi = base64en.encode(byteMi);  } catch (Exception e) {   e.printStackTrace();  } finally {   base64en = null;   byteMing = null;   byteMi = null;  }  return strMi; } /**  * 解密 以String密文输入,String明文输出  *   * @param strMi  * @return  */ public String getDesString(String strMi) {  BASE64Decoder base64De = new BASE64Decoder();  byte[] byteMing = null;  byte[] byteMi = null;  String strMing = "";  try {   byteMi = base64De.decodeBuffer(strMi);   byteMing = this.getDesCode(byteMi);   strMing = new String(byteMing, "UTF8");  } catch (Exception e) {   e.printStackTrace();  } finally {   base64De = null;   byteMing = null;   byteMi = null;  }  return strMing; } /**  * 加密以byte[]明文输入,byte[]密文输出  *   * @param byteS  * @return  */ private byte[] getEncCode(byte[] byteS) {  byte[] byteFina = null;  Cipher cipher;  try {   cipher = Cipher.getInstance("DES");   cipher.init(Cipher.ENCRYPT_MODE, key);   byteFina = cipher.doFinal(byteS);  } catch (Exception e) {   e.printStackTrace();  } finally {   cipher = null;  }  return byteFina; } /**  * 解密以byte[]密文输入,以byte[]明文输出  *   * @param byteD  * @return  */ private byte[] getDesCode(byte[] byteD) {  Cipher cipher;  byte[] byteFina = null;  try {   cipher = Cipher.getInstance("DES");   cipher.init(Cipher.DECRYPT_MODE, key);   byteFina = cipher.doFinal(byteD);  } catch (Exception e) {   e.printStackTrace();  } finally {   cipher = null;  }  return byteFina; } public static void main(String[] args) {  System.out.println("des demo");  DesEncrypt des = new DesEncrypt();// 实例化一个对像  des.getKey("MYKEY");// 生成密匙  System.out.println("key=MYKEY");  String strEnc = des.getEncString("111111");// 加密字符串,返回String的密文  System.out.println("密文=" + strEnc);  String strDes = des.getDesString(strEnc);// 把String 类型的密文解密  System.out.println("明文=" + strDes); }}


 

2. hibernate 数据库连接密码处理 
将Hibernate 的数据库连接密码加密放在配置文件和数据库中,具体spring+hibernate 连接配置修改连接如下:

步骤1: 将spring 关于数据源的连接修改如下:

 

Java代码 1.

<bean id="dataSource" class="com.ncs.pki.util.MyBasicDataSource" destroy-method="close">        <property name="driverClassName">            <value>oracle.jdbc.driver.OracleDriver</value>        </property>        <property name="url">            <value>jdbc:oracle:thin:@dbServer:1521:feelview</value>        </property>        <property name="username">            <value>feelview</value>        </property>        <property name="password">            <value>${jdbc.password}value>        </property>    </bean> 


 

解析:

dataSource 的 class 由 org.apache.commons.dbcp.BasicDataSource 改为自己创建的 com.hqlTest.MyBasicDataSource ;

BasicDataSource 类所做的事只有二件:1,继承 BasicDataSource ;2 ,重写 (override) 密码设置方法 setPassword ;函数 setPassword 中实现密码的 3DES 解密;

MyBasicDataSource代码:

 

import java.sql.SQLException;import org.apache.commons.dbcp.BasicDataSource;public class MyBasicDataSource extends BasicDataSource {  @Override public synchronized void setPassword(String password) {  //读取jdbc.Properties配置文件中加密后的密码  PropertiesUtils pro=new PropertiesUtils();  pro.getFile("jdbc.properties");  String passwordEncString=pro.read("jdbc.password");  pro.close();  System.out.println("password-->"+passwordEncString);  //将密码解密  DesEncrypt des=new DesEncrypt();  des.getKey("MYKEY");//生成密匙  password= des.getDesString(passwordEncString);// 把String 类型的密文解密  System.out.println("明文=" + password);  super.setPassword(password); } /**  * @param args  */ public static void main(String[] args) {  // TODO Auto-generated method stub  MyBasicDataSource mbds=new MyBasicDataSource();  System.out.println(mbds.getPassword()); }}


3.PropertiesUtils:

import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.Properties;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;  public class PropertiesUtils { /**  * ???? 2006 2006-8-18 ????01:40:49  * 得到文件的输入流  **/ private static Properties file = new Properties();   public void getFile(String fileName){//  Resource resource=new ClassPathResource(fileName);  InputStream inputStream = getClass().getResourceAsStream("/"+fileName);  if(inputStream==null){   System.out.println(fileName+" is  exist!");  }  else{   try {    file.load(inputStream);    inputStream.close();   } catch (IOException e) {    e.printStackTrace();   }  } } /**  * @param propertyName  读取 和写入  * @return  key  */ public String read(String propertyName){  return  file.getProperty(propertyName); } public void write(String name,String value){  file.setProperty(name, value); }  /**  * 关闭文件  */ public void close(){  try {   OutputStream os=new FileOutputStream("jdbc.properties");   file.store(os,null);   /*OutputStream os=new FileOutputStream("src/jdbc.xml");   prop.storeToXML(os,null);*/   os.close();  }catch (Exception e) {   System.out.println("jdbc.properties无法正常关闭");  } } /**  * 测试  */ public static void main(String[] args){  PropertiesUtils util = new PropertiesUtils();  util.getFile("jdbc.properties");  util.write("jdbc.port","10080");  util.write("jdbc.username","9999");  util.close();  String value=util.read("jdbc.url");  System.out.println("value-->"+value); }}



jdbc.Properties :

jdbc.driverClassName=com.MySQL.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test
jdbc.username=root
jdbc.password=Ey4pNYUPLxE=


 

==========================================

住:如果是在Linux系统下面,会出现登录不上的异常,

修改DesEncrypt.java类中的getkey方法: 

   

 /**      * 根据参数生成KEY      *       * @param strKey      */     public void getKey(String strKey) {      try {       KeyGenerator _generator = KeyGenerator.getInstance("DES");//       _generator.init(new SecureRandom(strKey.getBytes()));       SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );         secureRandom.setSeed(strKey.getBytes());         _generator.init(secureRandom);                this.key = _generator.generateKey();       _generator = null;      } catch (Exception e) {                  e.printStackTrace();      }     }


     原因是

SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又調用了 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。
参考:http://blog.csdn.net/hbcui1984/article/details/5753083
2 0
原创粉丝点击