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进行加密查询,这是项目中用到的,所以给大家分享一下,希望能给大家提供帮助。

时间: 2024-07-31 22:10:38

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

用PHP和Ajax进行前后台数据交互——以用户登录为例

很多网站中都有用户登录系统,要完成用户的注册和登陆,就一定要用到前后台的数据交互.在这里以简单的用户注册和登陆为例介绍一下前后台交互的大致流程. 首先,我们来做一个简单的登陆界面. 这里为了方便我使用了bootstrap插件 <form class="form-horizontal"> <div class="form-group"> <label>用户名</label> <input type="te

统一前后台数据交互格式

公司前后台数据交互的格式是统一的,前台对jquery的ajax方法进行了一些封装,也就是说开发的时候并不是自己去调用$.ajax方法,而是调用统一的方法去处理. 我感觉还是比较方便的..确实可以少写一些代码(因为通用代码被封装了),而且管理起来比较方便,统一..然后观察了一些网上的其他网站...发现很多网站都是这么做的...于是我也想自己动手来试试....我自己是使用springmvc与fastjson来实现的...下面分享一下我的经验. 网上例子: 首先先来找个网上的例子: 这个页面的地址是h

ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据的传递

前言 最近公司项目进行架构调整,由原来的三层架构改进升级到微服务架构(准确的说是服务化,还没完全做到微的程度,颗粒度没那么细),遵循RESTFull规范,使前后端完全分离,实现大前端思想.由于是初次尝试,中途也遇到了不少问题.今天就来讨论一下其中之一的问题,WebAPI与前端Ajax 进行跨域数据交互时,由于都在不同的二级域名下(一级域名相同),导致Cookies数据无法获取. 最开始通过头部(Header)将Cookies传输到其WebAPI,也能解决问题. 下面讲述另外一种解决方案. 解决过

ASP.Net中关于WebAPI与Ajax进行跨域数据交互时Cookies数据的传递

本文主要介绍了ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据传递的相关知识.具有很好的参考价值.下面跟着小编一起来看下吧 前言 最近公司项目进行架构调整,由原来的三层架构改进升级到微服务架构(准确的说是服务化,还没完全做到微的程度,颗粒度没那么细),遵循RESTFull规范,使前后端完全分离,实现大前端思想.由于是初次尝试,中途也遇到了不少问题.今天就来讨论一下其中之一的问题,WebAPI与前端Ajax 进行跨域数据交互时,由于都在不同的二级域名下(一级域名相同),导

jQuery Ajax 前端和后端数据交互的问题

原理:前端与后端的数据交互,最常用的就是GET.POST,比较常用的用法是:提交表单数据到后端,后端返回json 前端的数据发送与接收1)提交表单数据2)提交JSON数据 后端的数据接收与响应1)接收GET请求数据2)接收POST请求数据3)响应请求 1.提交表单数据 1)GET请求 1 var data = { 2 "name": "test", 3 "age": 1 4 }; 5 $.ajax({ 6 type: 'GET', 7 url:

关于蓝牙通信的数据AES128 ECB加密解密

因为AES128-ecb加密密钥采用了256位(32字节)的形式,而AES加密的位数是和密钥长度挂钩的,所以在刚拿到蓝牙协议的时候,一脸懵逼.为啥16字节的数据通过AES128-ecb加密后还是16个字节,此时我一直认为应该是32个字节(因为我测试也是返回的32个字节,没毛病啊?) 但是,这是有问题的! 首先来看下我们的蓝牙数据加密数据的格式: key:  需加密数据:  加密后结果: 发送16个字节,加密后也是16个字节.没办法啊,只能去看AES128 ECB加密的代码了.后面发现确实之前的加

springMVC前后台数据交互

假设项目需求是在springMVC框架下,后台要传送一个list到前台,那我们就要做以下几个步骤: 1 在web.xml文件中进行springMVC的配置: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://

在Java中Highcharts前后台数据交互传输

最近在项目中要添加一个Highcharts数据图表显示.看过官方的Ajax交互事例,可惜好像使用的是PHP语言,而且没有显示后台的代码.百度查看了很多前辈们的事例,发现没一样是我所要的效果...最后还是自己试着写写.今天却成功了!我后台用的是SSH框架.在此把此经验分享给大家. Highcharts其实还是满简单的,有点像一个框架一样,因为步骤单一而简单,只要自己在各个步骤中改一改自己想要的效果就出来了,在此我就不介绍这方面的知识了,有兴趣的可以上中文官方查看事例或学习.Highcharts中文

asp.net使用easyUI 前后台数据交互

// 1. asp页面使用EasyUI框架需要的Css样式和JS <script src="../script/jquery-easyui-1.4.5/jquery.min.js" type="text/javascript" charset = "utf-8"></script> <script src="../script/jquery-easyui-1.4.5/jquery.easyui.min.js