AJAX+REA实现前后台数据交互的加密解密
1、创建js文件Encryption.js
- /**
- *加密解密
- */
- /**RSA加密用生成key*/
- functionbodyRSA(){
- /**1024位的key参数写130,2014位的key参数写260*/
- setMaxDigits(130);
- /**ajax调用后台方法,取回公钥*/
- varkeyR;
- $.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函数三个参数:加密指数、解密指数、系数*/
- returnnewRSAKeyPair("10001","",keyR);
- }
- /**AES加密用随机生成key和iv*/
- functionrandomString(){
- varchars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- varlength=chars.length;
- varpwd='';
- for(vari=0;i<16;i++){
- pwd+=chars.charAt(Math.floor(Math.random()*length));
- }
- returnpwd;
- }
- /**
- *AES加密
- *@paramdata
- *@paramkey
- *@paramiv
- *@returns
- */
- functiongetAesString(data,key,iv){
- varkey=CryptoJS.enc.Utf8.parse(key);
- variv=CryptoJS.enc.Utf8.parse(iv);
- varencrypted=CryptoJS.AES.encrypt(data,{
- iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7
- });
- returnencrypted.toString();
- }
- /**
- *AES解密
- *@paramencrypted
- *@paramkey
- *@paramiv
- *@returns
- */
- functiongetDAesString(encrypted,iv){
- varkey=CryptoJS.enc.Utf8.parse(key);
- variv=CryptoJS.enc.Utf8.parse(iv);
- vardecrypted=CryptoJS.AES.decrypt(encrypted,padding:CryptoJS.pad.Pkcs7
- });
- returndecodeURIComponent(decrypted.toString(CryptoJS.enc.Utf8)).replace("+","");
- }
2、ajax请求后台的java类(1)
- packagecom.djzh.basicdata.controller;
- importorg.springframework.stereotype.Controller;
- importorg.springframework.web.bind.annotation.RequestMapping;
- importorg.springframework.web.bind.annotation.ResponseBody;
- importcom.djzh.common.utils.EncryptionDecryption;
- /**
- *获取RSA密钥文件中的公钥
- *@author:hanlin
- *@date:2017年2月3日下午3:32:31
- *@version:1.0
- */
- @Controller
- @RequestMapping("/Key")
- publicclassPublicKeyController{
- /**
- *获取RSA密钥文件中的公钥
- *@returnString类型
- */
- @RequestMapping("/pk")
- @ResponseBody
- publicStringgetPublicKey(){
- /**实例化加密解密工具类*/
- EncryptionDecryptioned=newEncryptionDecryption();
- returned.getPublicKey();
- }
- }
3、ajax请求后台的java类(2)--rea加解密的工具类
- EncryptionDecryption.java
- packagecom.djzh.common.utils;
- importjava.io.ByteArrayOutputStream;
- importjava.io.FileInputStream;
- importjava.io.FileOutputStream;
- importjava.io.ObjectInputStream;
- importjava.io.ObjectOutputStream;
- importjava.io.UnsupportedEncodingException;
- importjava.net.URLDecoder;
- importjava.net.URLEncoder;
- importjava.security.InvalidAlgorithmParameterException;
- importjava.security.InvalidKeyException;
- importjava.security.KeyPair;
- importjava.security.KeyPairGenerator;
- importjava.security.NoSuchAlgorithmException;
- importjava.security.PrivateKey;
- importjava.security.SecureRandom;
- importjavax.crypto.BadPaddingException;
- importjavax.crypto.Cipher;
- importjavax.crypto.IllegalBlockSizeException;
- importjavax.crypto.NoSuchPaddingException;
- importjavax.crypto.spec.IvParameterSpec;
- importjavax.crypto.spec.SecretKeySpec;
- importorg.apache.commons.codec.binary.Base64;
- importorg.apache.log4j.Logger;
- /**
- *rsaaes加密解密工具类
- *Title:EncryptionDecryption
- *Company:djzh
- *@authorhanlin
- *@date2017年1月17日上午11:02:50
- */
- publicclassEncryptionDecryption{
- /**密钥文件存储位置*/
- privatestaticStringRSAKeyStore="C:/RSAKey.txt";//在这个位置放这个文件
- /**
- *日志记录器
- */
- publicstaticLoggerlogger=Logger.getLogger(EncryptionDecryption.class);
- /**
- *AES加密
- *@paramcontent明文
- *@paramkeyBytes秘钥
- *@paramiv偏移量
- *@return
- */
- publicstaticStringAES_CBC_Encrypt(Stringcontent,byte[]keyBytes,byte[]iv){
- try{
- SecretKeySpeckey=newSecretKeySpec(keyBytes,"AES");
- Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
- cipher.init(Cipher.ENCRYPT_MODE,newIvParameterSpec(iv));
- content=URLEncoder.encode(content,"UTF-8");//用url编码
- byte[]result=cipher.doFinal(content.getBytes());//加密
- returnnewString(Base64.encodeBase64(result),"UTF-8");
- }catch(NoSuchPaddingExceptione){
- e.printStackTrace();
- }catch(NoSuchAlgorithmExceptione){
- e.printStackTrace();
- }catch(UnsupportedEncodingExceptione){
- e.printStackTrace();
- }catch(InvalidKeyExceptione){
- e.printStackTrace();
- }catch(IllegalBlockSizeExceptione){
- e.printStackTrace();
- }catch(BadPaddingExceptione){
- e.printStackTrace();
- }catch(InvalidAlgorithmParameterExceptione){
- e.printStackTrace();
- }
- returnnull;
- }
- /**
- *AES解密
- *@paramcontent密文
- *@paramkeyBytes秘钥
- *@paramiv偏移量
- *@return
- */
- publicstaticStringAES_CBC_Decrypt(Stringcontent,byte[]iv){
- try{
- content=content.replaceAll("","+");
- byte[]decryptBaseData=Base64.decodeBase64(content.getBytes("utf-8"));
- SecretKeySpeckey=newSecretKeySpec(keyBytes,"AES");
- Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
- cipher.init(Cipher.DECRYPT_MODE,newIvParameterSpec(iv));
- byte[]result=cipher.doFinal(decryptBaseData);
- returnURLDecoder.decode(newString(result),"utf-8");
- }catch(NoSuchPaddingExceptione){
- e.printStackTrace();
- }catch(NoSuchAlgorithmExceptione){
- e.printStackTrace();
- }catch(UnsupportedEncodingExceptione){
- e.printStackTrace();
- }catch(InvalidKeyExceptione){
- e.printStackTrace();
- }catch(IllegalBlockSizeExceptione){
- e.printStackTrace();
- }catch(BadPaddingExceptione){
- e.printStackTrace();
- }catch(InvalidAlgorithmParameterExceptione){
- e.printStackTrace();
- }
- returnnull;
- }
- /**
- *字符串转为byte[]
- *@paramhexString
- *@return
- */
- publicstaticbyte[]hexStringToBytes(StringhexString){
- if(hexString==null||hexString.equals("")){
- returnnull;
- }
- hexString=hexString.toUpperCase();
- intlength=hexString.length()/2;
- char[]hexChars=hexString.tocharArray();
- byte[]d=newbyte[length];
- for(inti=0;i<length;i++){
- intpos=i*2;
- d[i]=(byte)(charToByte(hexChars[pos])<<4|charToByte(hexChars[pos+1]));
- }
- returnd;
- }
- /**
- *Convertchartobyte
- *@paramcchar
- *@returnbyte
- */
- privatestaticbytecharToByte(charc){
- return(byte)"0123456789ABCDEF".indexOf(c);
- }
- /**
- *解密由RSA加密的AES的key和iv
- *@parampara
- *@return
- *@throwsException
- */
- publicstaticbyte[]getValue(Stringparam)throwsException{
- byte[]trueValue=null;
- try{
- if(!param.equals("")&¶m!=null){
- byte[]KeyB=hexStringToBytes(param);
- KeyB=decrypt(getKeyPair().getPrivate(),KeyB);
- StringBuffersbKey=newStringBuffer();
- sbKey.append(newString(KeyB));
- param=sbKey.reverse().toString();
- trueValue=URLDecoder.decode(param,"UTF-8").getBytes();
- }
- }catch(Exceptione){
- //重要参数值
- logger.error("传入参数:"+"param:"+param);
- //异常说明
- logger.error("解密由RSA加密的AES的key和iv失败,可能前台传入的aKey或者aIv为空");
- e.printStackTrace();
- }
- returntrueValue;
- }
- /**
- *获取密钥文件中的公钥
- *@return
- */
- publicStringgetPublicKey(){
- ObjectpublicKey=null;
- StringpublicKEY=null;
- try{
- publicKey=getKeyPair().getPublic();
- publicKEY=(String)publicKey.toString().subSequence(37,293);
- }catch(Exceptione){
- e.printStackTrace();
- }
- returnpublicKEY;
- }
- /**
- *RSA生成密钥对
- *@return
- *@throwsException
- */
- publicstaticKeyPairgenerateKeyPair()throwsException{
- try{
- KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());
- finalintKEY_SIZE=1024;
- keyPairGen.initialize(KEY_SIZE,newSecureRandom());
- KeyPairkeyPair=keyPairGen.generateKeyPair();
- FileOutputStreamfos=newFileOutputStream(RSAKeyStore);
- ObjectOutputStreamoos=newObjectOutputStream(fos);
- oos.writeObject(keyPair);
- oos.close();
- fos.close();
- returnkeyPair;
- }catch(Exceptione){
- thrownewException(e.getMessage());
- }
- }
- /**
- *获取密钥对
- *@return
- *@throwsException
- */
- publicstaticKeyPairgetKeyPair()throwsException{
- FileInputStreamfis=newFileInputStream(RSAKeyStore);
- ObjectInputStreamoos=newObjectInputStream(fis);
- KeyPairkp=(KeyPair)oos.readObject();
- oos.close();
- fis.close();
- returnkp;
- }
- /**
- *解密
- *@parampk
- *@paramraw
- *@return
- *@throwsException
- */
- @SuppressWarnings("static-access")
- privatestaticbyte[]decrypt(PrivateKeypk,byte[]raw)throwsException{
- try{
- Ciphercipher=Cipher.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());
- cipher.init(cipher.DECRYPT_MODE,pk);
- intblockSize=cipher.getBlockSize();
- ByteArrayOutputStreambout=newByteArrayOutputStream(64);
- intj=0;
- while(raw.length-j*blockSize>0){
- bout.write(cipher.doFinal(raw,j*blockSize,blockSize));
- j++;
- }
- returnbout.toByteArray();
- }catch(Exceptione){
- thrownewException(e.getMessage());
- }
- }
- }
- C:/RSAKey.txt
5、在JSP页面导入Encryption.js,通过ajax进行加密请求
- functiondataAjaxRefer(){
- //筛选条件的参数进行加密
- varkeyRSA=bodyRSA();//生成RSA加密用的key
- varkey=randomString();//随机生成AES的key和iv
- variv=randomString();
- varaKey=encryptedString(keyRSA,encodeURIComponent(key));//RSA加密AES的key
- varaIv=encryptedString(keyRSA,encodeURIComponent(iv));//RSA加密AES的iv
- varselect1=$("#jffpqh").val();//参数1
- varselectText1_=getAesString(encodeURIComponent(select1),iv);//AES参数内容1
- //筛选条件的参数
- vardata={
- 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){
- vardecryptedStr=getDAesString(data,iv);//解密
- }
- },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进行加密查询,这是项目中用到的,所以给大家分享一下,希望能给大家提供帮助。