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