您的位置:首页 > 其它

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

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

附件:http://down.51cto.com/data/2366466
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ajax 加密解密 rsa