AJAX+REA实现前后台数据交互的加密解密

1、创建js文件Encryption.js

/**
 * 加密解密
 */

/** RSA加密用 生成key */
function bodyRSA(){
	/** 1024位的key参数写130,2014位的key参数写260 */
	setMaxDigits(130);
	/** ajax 调用后台方法,取回公钥 */
	var keyR ;
    $.ajax({
    	url: "/GHGL/Key/pk",//请求后台的url,本例是springMVC框架
        type: "post",
        cache: false,
        async : false,
        dataType: "text",
        success: function (data)
        {
        	keyR = data;
        },
        error:function (XMLHttpRequest, textStatus, errorThrown) {      
            alert("与服务器连接失败!");
        }
     });
	/** RSAKeyPair 函数三个参数:加密指数、解密指数、系数 */
	return new RSAKeyPair("10001","",keyR);
}

/** AES加密用 随机生成key和iv */
function randomString() {
	var chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
	var length= chars.length;
	var pwd='';
	for(var i = 0; i < 16 ;i++){
		pwd += chars.charAt(Math.floor(Math.random() * length));
	}
	return pwd;
}
/**
 * AES加密
 * @param data
 * @param key
 * @param iv
 * @returns
 */
function getAesString(data,key,iv){
    var key  = CryptoJS.enc.Utf8.parse(key);
    var iv   = CryptoJS.enc.Utf8.parse(iv);
    var encrypted = CryptoJS.AES.encrypt(data,key,
            {
                iv:iv,
                mode:CryptoJS.mode.CBC,
                padding:CryptoJS.pad.Pkcs7
            });
    return encrypted.toString();
}
/**
 * AES解密
 * @param encrypted
 * @param key
 * @param iv
 * @returns
 */
function getDAesString(encrypted,key,iv){
    var key  = CryptoJS.enc.Utf8.parse(key);
    var iv   = CryptoJS.enc.Utf8.parse(iv);
    var decrypted = CryptoJS.AES.decrypt(encrypted,key,
            {
                iv:iv,
                mode:CryptoJS.mode.CBC,
                padding:CryptoJS.pad.Pkcs7
            });
    return decodeURIComponent(decrypted.toString(CryptoJS.enc.Utf8)).replace("+", " ");
}

2、ajax请求后台的java类(1)

    

package com.djzh.basicdata.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.djzh.common.utils.EncryptionDecryption;

/**
 * 获取RSA密钥文件中的公钥
 * @author       : hanlin
 * @date         : 2017年2月3日 下午3:32:31
 * @version      : 1.0
 */

@Controller
@RequestMapping("/Key")
public class PublicKeyController {
	
	/**
	 * 获取RSA密钥文件中的公钥
	 * @return String类型
	 */
	@RequestMapping("/pk")
	@ResponseBody 
	public String getPublicKey(){
		/** 实例化加密解密工具类*/
		EncryptionDecryption ed = new EncryptionDecryption();
		return ed.getPublicKey();
	}
}

3、ajax请求后台的java类(2)--rea加解密的工具类

EncryptionDecryption.java

    

package com.djzh.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

/**
 * rsa aes 加密解密工具类
 * Title: EncryptionDecryption
 * Company: djzh
 * @author hanlin
 * @date 2017年1月17日 上午11:02:50
 */


public class EncryptionDecryption {

	/** 密钥文件存储位置 */
	private static String RSAKeyStore = "C:/RSAKey.txt";//在这个位置放这个文件
	
    /**
     * 日志记录器
     */
    public static Logger logger = Logger.getLogger(EncryptionDecryption.class);
    
	/**
	 * AES加密
	 * @param content  明文
	 * @param keyBytes 秘钥
	 * @param iv      偏移量
	 * @return   
	 */	
    public static String AES_CBC_Encrypt(String content, byte[] keyBytes, byte[] iv){  
          
        try{ 
            SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");  
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));  
            content = URLEncoder.encode(content,"UTF-8");   //用url编码
            byte[] result=cipher.doFinal(content.getBytes()); //加密
            return new String(Base64.encodeBase64(result),"UTF-8");
        }catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		} 
        return null;
    }
    
    /**
     * AES解密
     * @param content   密文
     * @param keyBytes  秘钥
     * @param iv        偏移量
     * @return          
     */
	public static String AES_CBC_Decrypt(String content, byte[] keyBytes, byte[] iv){  
          
        try{  
        	content = content.replaceAll(" ", "+");
        	byte[] decryptBaseData=Base64.decodeBase64(content.getBytes("utf-8"));
            SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");  
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));  
            byte[] result=cipher.doFinal(decryptBaseData);  
            return URLDecoder.decode(new String(result),"utf-8");  
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		}   
        return null;  
    }
    
    /**
     * 字符串转为 byte[]
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }
    
    /**
     * Convert char to byte
     * @param c char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
    
    /**
     * 解密由RSA加密的AES的key 和 iv
     * @param para
     * @return
     * @throws Exception
     */
    public static byte[] getValue(String param) throws Exception{
    	byte[] trueValue = null;
		try {
			if(!param.equals("") && param != null){
				byte[] KeyB = hexStringToBytes(param);
				KeyB = decrypt(getKeyPair().getPrivate(),KeyB);
				StringBuffer sbKey = new StringBuffer();
				sbKey.append(new String(KeyB));
				param = sbKey.reverse().toString();
				trueValue = URLDecoder.decode(param,"UTF-8").getBytes(); 
			}			
		} catch (Exception e) {
			//重要参数值
			logger.error("传入参数:" + "param: " + param);
			//异常说明
			logger.error("解密由RSA加密的AES的key 和 iv 失败,可能前台传入的aKey或者aIv为空");
			e.printStackTrace();
		}
		return trueValue; 
    }
    
    /**
     * 获取密钥文件中的公钥
     * @return
     */
    public String getPublicKey(){
    	Object publicKey = null;
    	String publicKEY = null;
		try {
			publicKey = getKeyPair().getPublic();
			publicKEY = (String) publicKey.toString().subSequence(37, 293);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return publicKEY;		
    }
    
    /**
     * RSA 生成密钥对
     * @return
     * @throws Exception
     */
	public static KeyPair generateKeyPair() throws Exception {
		try {
			KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			final int KEY_SIZE = 1024;
			keyPairGen.initialize(KEY_SIZE, new SecureRandom());
			KeyPair keyPair = keyPairGen.generateKeyPair();
			FileOutputStream fos = new FileOutputStream(RSAKeyStore);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(keyPair);
			oos.close();
			fos.close();
			return keyPair;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * 获取密钥对
	 * @return
	 * @throws Exception
	 */
	public static KeyPair getKeyPair() throws Exception {
		FileInputStream fis = new FileInputStream(RSAKeyStore);
		ObjectInputStream oos = new ObjectInputStream(fis);
		KeyPair kp = (KeyPair) oos.readObject();
		oos.close();
		fis.close();
		return kp;
	}

	/**
	 * 解密
	 * @param pk
	 * @param raw
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("static-access")
	private static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			cipher.init(cipher.DECRYPT_MODE, pk);
			int blockSize = cipher.getBlockSize();
			ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
			int j = 0;

			while (raw.length - j * blockSize > 0) {
				bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
				j++;
			}
			return bout.toByteArray();
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}
}

4、在某个盘的位置放这个文件,上面代码里调用了。见附件

C:/RSAKey.txt

5、在JSP页面导入Encryption.js,通过ajax进行加密请求

function dataAjaxRefer(){
	
	//筛选条件的参数进行加密
	var keyRSA = bodyRSA(); //生成RSA加密用的key
	var key  = randomString();//随机生成AES的key 和 iv	    
	var iv   = randomString();
	var aKey = encryptedString(keyRSA, encodeURIComponent(key)); //RSA加密AES的key
	var aIv = encryptedString(keyRSA, encodeURIComponent(iv)); //RSA加密AES的iv
	
	
	
	var select1=$("#jffpqh").val();//参数1
	var selectText1_ = getAesString(encodeURIComponent(select1),key,iv); //AES参数内容1
	
	//筛选条件的参数
	var data={
		jffpqh:selectText1_, //参数1
		aKey:aKey, 
		aIv:aIv
	}
	//console.log(data)
	$.ajax({
		type:"post",
		url:"/GHGL/Distribution/showFundsTerm",//请求的url,本例为springMVC框架
		async:true,
		data:data,
		dataType:"json",
		success:function(data){
		
			var decryptedStr = getDAesString(data,key,iv);//解密
			}				
			},
		error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(XMLHttpRequest.status);
            alert(XMLHttpRequest.readyState);
            alert(textStatus);
        },
        complete: function(XMLHttpRequest, textStatus) {
            this; // 调用本次AJAX请求时传递的options参数
        }
	});
}

6、总结: 首先创建js文件,里面包含生成加密解密的 key 和iv、加密方法、机密方法,然后在后台写好相应的生成key,IV的工具类,工具类会读取 rsa.txt文件,然后通过js调用ajax进行加密查询,这是项目中用到的,所以给大家分享一下,希望能给大家提供帮助。