记项目关于绩效加密的一些问题

需求:

1、只导入绩效基础数据,有些数据需要计算得出(excel公式一键生成的东西,硬要这样玩,真是无语)

2、绩效数据全要加密。

 

期间碰到了

    1、关于org.apache.commons.beanutils.BeanUtils中 String转Date的问题。

    2、des对称加密。

    3、由于字段太多(50多个。。),所以利用反射去加密,不然写的累死了

 

第一个问题:关于org.apache.commons.beanutils.BeanUtils中 String转Date的问题。

    因为有些数据需要计算,所以一开始关于绩效的数据是用float类型去接的(利用easypoi),计算是利用BigDecimal(不然精度会有误),然后因为要加密,之后会转换成String的类型。

    根据BeanUtils.copyProperties( , )  float类型是可以成功转成String类型的,但是String类型不能转成Date类型。

    所以在执行copyProperties方法之前,注册一个转换器。

ConvertUtils.register(new Converter()    
		    {    
		        @SuppressWarnings("rawtypes")    
		        @Override    
		        public Object convert(Class arg0, Object arg1)    
		        {    
		            if(arg1 == null)    
		            {    
		                return null;    
		            }    
		            if(!(arg1 instanceof String))    
		            {    
		                throw new ConversionException("只支持字符串转换 !");    
		            }    
		            String str = (String)arg1;    
		            if(str.trim().equals(""))    
		            {    
		                return null;    
		            }    
		            SimpleDateFormat sd = new SimpleDateFormat("yyyyMM");  //这里自定义转换  
		                 
		            try{    
		                return sd.parse(str);    
		            }    
		            catch(ParseException e)    
		            {    
		                throw new RuntimeException(e);    
		            }    
		                 
		        }    
		             
		    }, java.util.Date.class);  

 

第二个问题:des加密,写了一个类,代码如下

import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
/**
 * 
 * des加密解密
 * @author gzc
 *
 */
public class DesUtil {
  
	    /**
	     * 获得秘钥
	     * @return
	     * @throws InvalidKeySpecException 
	     */
	    public static Key getDesKey() {
	        //1.初始化key秘钥   
	    	Key key=null;
			try {
				 KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");  
		            keyGenerator.init(new SecureRandom());  
		            SecretKey secretKey= keyGenerator.generateKey();  
		            //转换key秘钥  
		            DESedeKeySpec deSedeKeySpec=new DESedeKeySpec(secretKey.getEncoded());  
		            SecretKeyFactory secretKeyFactory=SecretKeyFactory.getInstance("DESede");  
		            key= secretKeyFactory.generateSecret(deSedeKeySpec);  
			} catch (Exception e) {
				e.printStackTrace();
			}  
	        return key;
	    }
	    
	    /**
	     * 对秘钥进行编码保存
	     * @param key
	     * @return
	     */
	    public static String getHexKey(Key key){
	        return HexBin.encode(key.getEncoded());
	    }  
	    
	    /**
	     * 加密float類型
	     * @param key 秘钥
	     * @param f 
	     * @return
	     */
	    public static String desEncode(Key key,float f){
	    	String desEncodeStr=null;
	        try {  
	            Cipher cipher=Cipher.getInstance("DESede/ECB/PKCS5Padding");  
	            cipher.init(Cipher.ENCRYPT_MODE, key);  
	            byte[] result= cipher.doFinal((f+"").getBytes());
	            desEncodeStr=HexBin.encode(result);
	        } catch (Exception e) {  
	            e.printStackTrace();  
	        } 
	        return desEncodeStr;
	    }
	    
	    /**
	     * 通过16位的编码秘钥,反推秘钥
	     * @param hexKey
	     * @return
	     */
	    public static Key getDesKey(String hexKey){  
	    	Key key=null;
	        try {  
	        	//解码,重新生成key
	            byte[] keybyte= HexBin.decode(hexKey);  
	        	DESedeKeySpec deSedeKeySpec=new DESedeKeySpec(keybyte);  
	            SecretKeyFactory secretKeyFactory=SecretKeyFactory.getInstance("DESede");  
	            key= secretKeyFactory.generateSecret(deSedeKeySpec); //获取到key秘钥  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	        } 
	        return key;
	    }
	    
	    
	    /**
	     * 解密
	     * @param key  秘钥
	     * @param encodeStr 需要解码的字符串
	     * @return
	     */
	    public static String desDecode(Key key,String encodeStr){  
	    	String resultStr=null;
	        try {  
	        //进行解密  
	            Cipher cipher=Cipher.getInstance("DESede/ECB/PKCS5Padding");  
	            cipher.init(Cipher.DECRYPT_MODE, key);  
	            byte[] result = cipher.doFinal(HexBin.decode(encodeStr));  
	            resultStr=new String(result);
	        } catch (Exception e) {  
	            e.printStackTrace();  
	        } 
	        return resultStr;
	    }
	    
}

 

第三个问题:利用反射去设置字段的加密、解密   写了一个工具类:

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Key;
import java.util.Arrays;

public class ReflectEncryption {
	
	/**
	 * 
	 * @param entity 需要加密的一个对象
	 * @param strs   需要加密的属性名数组
	 * @param key    秘钥
	 * @throws Exception
	 */
	public static  <T> void encode(T entity,String[] strs,Key key) throws  Exception{
		//得到Class
		Class clazz =entity.getClass();
		//得到属性名数组 
		Field[] fields = clazz.getDeclaredFields();
		 
		 for(Field f : fields){
			 if(Arrays.asList(strs).contains(f.getName())){
				 //用来得到属性的get和set方法
				 PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);
				 //得到set方法
				 Method setMethod=pd.getWriteMethod();
				 //得到get方法
				 Method getMethod=pd.getReadMethod();
				 //加密
				 setMethod.invoke(entity, DesUtil.desEncode(key, Float.parseFloat((String)getMethod.invoke(entity))));
			 }
		 }
	}
	
	public static  <T> void decode(T entity,String[] strs,Key key) throws Exception {
		Class clazz =entity.getClass();
		 Field[] fields = clazz.getDeclaredFields();
		 
		 for(Field f : fields){
			 if(Arrays.asList(strs).contains(f.getName())){
				 PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);
				 Method setMethod=pd.getWriteMethod();
				 Method getMethod=pd.getReadMethod();
				 setMethod.invoke(entity, DesUtil.desDecode(key, (String)getMethod.invoke(entity)));
			 }
		 }
	}
	
	
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值