AJAX+REA實現前後臺數據交互的加密解密

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進行加密查詢,這是項目中用到的,所以給大家分享一下,希望能給大家提供幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章