先了解AES和RSA加密算法
AES算法
1、运算速度快,在有反馈模式、无反馈模式的软硬件中,Rijndael都表现出非常好的性能。
2、对内存的需求非常低,适合于受限环境。
3、Rijndael 是一个分组迭代密码, 分组长度和密钥长度设计灵活。
4、AES标准支持可变分组长度,分组长度可设定为32 bit的任意倍数,最小值为128 bit,最大值为256 bit。
5、AES的密钥长度比DES大, 它也可设定为32 比特的任意倍数,最小值为128bit,最大值为256 bit,所以用穷举法是不可能破解的。
7、AES算法的设计策略是WTS。WTS 是针对差分分析和线性分析提出的,可对抗差分密码分析和线性密码分析。
RSA算法
RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其难,因此可以将乘积公开作为加密密钥。
一般来说有两种用途:
一、公钥加密
假设一下,我找了两个数字,一个是1,一个是2。我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉大家,1是我的公钥。
我有一个文件,不能让别人看,我就用1加密了。别人找到了这个文件,但是他不知道2就是解密的私钥啊,所以他解不开,只有我可以用
数字2,就是我的私钥,来解密。这样我就可以保护数据了。
我的好朋友x用我的公钥1加密了字符a,加密后成了b,放在网上。别人偷到了这个文件,但是别人解不开,因为别人不知道2就是我的私钥,
只有我才能解密,解密后就得到a。这样,我们就可以传送加密的数据了。
二、私钥签名
如果我用私钥加密一段数据(当然只有我可以用私钥加密,因为只有我知道2是我的私钥),结果所有的人都看到我的内容了,因为他们都知
道我的公钥是1,那么这种加密有什么用处呢?
但是我的好朋友x说有人冒充我给他发信。怎么办呢?我把我要发的信,内容是c,用我的私钥2,加密,加密后的内容是d,发给x,再告诉他
解密看是不是c。他用我的公钥1解密,发现果然是c。
这个时候,他会想到,能够用我的公钥解密的数据,必然是用我的私钥加的密。只有我知道我得私钥,因此他就可以确认确实是我发的东西。
这样我们就能确认发送方身份了。这个过程叫做数字签名。当然具体的过程要稍微复杂一些。用私钥来加密数据,用途就是数字签名。
总结:公钥和私钥是成对的,它们互相解密。
公钥加密,私钥解密。
私钥数字签名,公钥验证。
接下来就是一个基于两种算法的前后端加解密Demo
加解密逻辑并不复杂,所以只写了一个controller层的代码
package com.example.rsa_aes_demo03.controller;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.SecretKey;
import javax.servlet.http.HttpServletRequest;
import com.example.rsa_aes_demo03.util.AESUtil;
import com.example.rsa_aes_demo03.util.RSAUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
/**
* @author LL
* @Description:
* @date
*/
@Controller
public class HomeController {
@RequestMapping("/")
public String index() {
return "index";
}
/**
* 获取公钥
*
* @return
*/
@ResponseBody
@GetMapping("/getPublicKey")
public Map<String, Object> getKey(HttpServletRequest request) throws Exception {
Map<String, String> keyMap = RSAUtil.createKeys(1024);
String publicKey = keyMap.get("publicKey");
String privateKey = keyMap.get("privateKey");
Map<String, String> maps = new HashMap<>();
maps.put("publickey", publicKey);
maps.put("privatekey", privateKey);
request.getSession().setAttribute("privateKey", privateKey);
// 构建反馈模型
Map<String, Object> map = new HashMap<>();
map.put("code", 0);
map.put("message", "success");
map.put("data", maps);
return map;
}
@ResponseBody
@PostMapping("/login")
public Map<String, Object> login(String content, HttpServletRequest request) throws Exception {
String privateKey = request.getSession().getAttribute("privateKey").toString();
String newContent = RSAUtil.privateDecrypt(content, RSAUtil.getPrivateKey(privateKey));
Map<String, String> maps = new HashMap<>();
maps.put("content", "解密后的内容: " + newContent);
// 构建反馈模型
Map<String, Object> map = new HashMap<>();
map.put("code", 0);
map.put("message", "success");
map.put("data", maps);
return map;
}
@GetMapping("/aesview")
public String aesView() {
return "aesview";
}
@ResponseBody
@RequestMapping("/getAesKey")
public Map<String,Object> aesKey(HttpServletRequest request){
String key = "AESD2524fegs2s5g";
String iv = "AESD2524fegs2s5g";
Map<String, String > maps=new HashMap<>();
maps.put("key",key);
maps.put("iv",iv);
Map<String, Object> map=new HashMap<>();
map.put("code",0);
map.put("message","success");
map.put("data",maps);
return map;
}
@ResponseBody
@PostMapping("/aesencode")
public String aesEncode(String encryptData, String key, String iv) {
// 加密
return null;
}
@ResponseBody
@PostMapping("/aes" )
public Map<String, Object> aesDncode(String content) {
// 解密
System.out.println("执行到aes代码");
String keys = "AESD2524fegs2s5g";
SecretKey key = AESUtil.stringToSecretKey(keys);
String decryptData = AESUtil.aesEcbDecrypt(content, key);
Map<String,String> mas = new HashMap<>();
mas.put("content",decryptData);
// 构建反馈模型
Map<String, Object> map = new HashMap<>();
map.put("code", 0);
map.put("message", "success");
map.put("data",mas );
return map;
}
}
这里还有个加密没有写完,但逻辑都是差不多的。
还需要两个工具类,
AESUtil
package com.example.rsa_aes_demo03.util;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES加密工具类
*/
public class AESUtil {
/**
* 字符集
*/
public static final String CHARSET = "UTF-8";
/**
* 参数分别代表 : 算法名称/加密模式/数据填充方式</br>
* 加密模式:</br>
* <li>1.电码本模式(Electronic Codebook Book (ECB))<li>
* 这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密
* 2.密码分组链接模式(Cipher Block Chaining (CBC))
* 这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
*/
public static final String AES_ALGORITHM = "AES";
// js使用PKCS7的补码方式,其实和PKCS5是一致的
public static final String ECB_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
public static final String CBC_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
/**
* AES理论上支持128,192,256三种长度的密钥,但是jdk只支持128位
*/
private static final int KEY_SIZE = 128;
/**
* IV(Initialization Value)是一个初始值,对于CBC模式来说,它必须是随机选取并且需要保密的
* 而且它的长度和密码分组相同(比如:对于AES 128为128位,即长度为16的byte类型数组)
*/
public static final byte[] IVPARAMETERS = new byte[]{1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16};
/**
* ECB模式加密
*
* @param encryptData 加密内容
* @param encryptKey 密钥(key)
* @return 返回Base64字符串
*/
public static String aesEcbEncrypt(String encryptData, SecretKey encryptKey) {
try {
Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, encryptKey);
byte[] src = cipher.doFinal(encryptData.getBytes(CHARSET));
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(src);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* ECB模式解密
*
* @param decryptData 密文(解密内容)
* @param decryptKey 密钥
* @return 解密后的内容
*/
public static String aesEcbDecrypt(String decryptData, SecretKey decryptKey) {
try {
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptBytes = decoder.decode(decryptData);
Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, decryptKey);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes, CHARSET);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* CBC模式加密
*
* @param encryptData 加密内容
* @param encryptKey 密钥
* @param iv 密钥偏移量
* @return 密文
*/
public static String aesCbcEncrypt(String encryptData, SecretKey encryptKey, String iv) {
try {
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(CHARSET));
Cipher cipher = Cipher.getInstance(CBC_CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, encryptKey, ivParameterSpec);
byte[] src = cipher.doFinal(encryptData.getBytes(CHARSET));
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(src);
} catch (Exception e) {
// TODO: handle exception
return null;
}
}
/**
* CBC模式解密
*
* @param decryptData 密文
* @param decryptKey 密钥
* @param iv 密钥偏移量
* @return 解密后的内容
*/
public static String aesCbcDecrypt(String decryptData, SecretKey decryptKey, String iv) {
try {
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptBytes = decoder.decode(decryptData);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(CHARSET));
Cipher cipher = Cipher.getInstance(CBC_CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, decryptKey, ivParameterSpec);
return new String(cipher.doFinal(encryptBytes), CHARSET);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 生成密钥
*
* @return
*/
public static SecretKey generateAESSecretKey() {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
keyGenerator.init(KEY_SIZE);
byte[] key = keyGenerator.generateKey().getEncoded();
return new SecretKeySpec(key, AES_ALGORITHM);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 生成密钥,根据传入的明文key生成,调用SecureRandom进行随机
*
* @param decryptKey
* @return
*/
public static SecretKey generateAESSecretKey(String decryptKey) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
keyGenerator.init(KEY_SIZE, new SecureRandom(decryptKey.getBytes()));
byte[] key = keyGenerator.generateKey().getEncoded();
return new SecretKeySpec(key, AES_ALGORITHM);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串key转为SecretKey
*
* @param key
* @return
*/
public static SecretKey stringToSecretKey(String key) {
try {
return new SecretKeySpec(key.getBytes("UTF-8"), "AES");
} catch (UnsupportedEncodingException e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
}
/**
* Ecb加密模式,推荐使用 aesEcbEncrypt方法<br>
* 这个方法使用了SecureRandom,所以前端加密的时候注意
*
* @param encodeRules 密钥
* @param data 加密内容
* @return
*/
@Deprecated
public static String aesEcbEncode(String encodeRules, String data) {
byte[] byte_AES = null;
try {
// 算法实例
KeyGenerator generator = KeyGenerator.getInstance(AES_ALGORITHM);
// 根据encodeRules规则初始化密钥生成器
generator.init(KEY_SIZE, new SecureRandom(encodeRules.getBytes()));
// 产生原始对称密钥
SecretKey old_key = generator.generateKey();
// 获取原始对称密钥的字节数组
byte[] raw = old_key.getEncoded();
// 根据字节数组生成ASE密钥
SecretKey key = new SecretKeySpec(raw, AES_ALGORITHM);
// 根据指定算法生成密码器
Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
// 初始化密码器,ENCRYPT_MODE 加密,
cipher.init(Cipher.ENCRYPT_MODE, key);
// 获取加密内容的字节数组,需要设置为UTF-8,不然中英文混合解密就会乱码
byte[] byte_encode = data.getBytes(CHARSET);
// 根据密码器初始化方式--加密:
byte_AES = cipher.doFinal(byte_encode);
// 将加密或的数据转换为字符串
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(byte_AES);
}
/**
* Ecb加密模式,推荐使用 aesEcbDncrypt方法<br>
* 这个方法使用了SecureRandom,所以前端加密的时候注意
*
* @param encodeRules 密钥
* @param data 加密内容
* @return
*/
@Deprecated
public static String aesEcbDncode(String encodeRules, String data) {
String AES_decode = null;
try {
// 1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keygen = KeyGenerator.getInstance(AES_ALGORITHM);
// 2.根据ecnodeRules规则初始化密钥生成器
// 生成一个128位的随机源,根据传入的字节数组
keygen.init(128, new SecureRandom(encodeRules.getBytes()));
// 3.产生原始对称密钥
SecretKey original_key = keygen.generateKey();
// 4.获得原始对称密钥的字节数组
byte[] raw = original_key.getEncoded();
// 5.根据字节数组生成AES密钥
SecretKey key = new SecretKeySpec(raw, AES_ALGORITHM);
// 6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
// 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.DECRYPT_MODE, key);
// 8.将加密并编码后的内容解码成字节数组
Base64.Decoder decoder = Base64.getDecoder();
byte[] byte_content = decoder.decode(data);
/*
* 解密
*/
byte[] byte_decode = cipher.doFinal(byte_content);
AES_decode = new String(byte_decode, CHARSET);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return AES_decode;
}
public static void main(String[] args) throws Exception {
String keys = "8NONwyJtHesysWpM";
System.out.println(keys.length());
SecretKey key = stringToSecretKey(keys);
//SecretKey key = generateAESSecretKey("13245");
String decryptData = AESUtil.aesEcbEncrypt("ABCDEFGH", key);
System.out.println("ECB模式 加密后:" + decryptData);
System.out.println("ECB模式 解密后:" + AESUtil.aesEcbDecrypt(decryptData, key));
String iv = "8NONwyJtHesysWpM";
String cbcDecryptData = AESUtil.aesCbcEncrypt("ABCDEFGH", key, iv);
System.out.println("CBC模式 加密后:" + cbcDecryptData);
System.out.println("CBC模式 解密后:" + AESUtil.aesCbcDecrypt(cbcDecryptData, key, iv));
}
}
最后的main 方法中 也展示了各个方法的使用。
RSAUtil
package com.example.rsa_aes_demo03.util;
import com.fasterxml.jackson.databind.ser.Serializers;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* RSA工具类
*/
public class RSAUtil {
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA";
public static Map<String, String> createKeys(int keySize) {
//为RSA算法创建一个KeyPairGenerator对象
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
//初始化KeyPairGenerator对象,密钥长度
kpg.initialize(keySize);
//生成密匙对
KeyPair keyPair = kpg.generateKeyPair();
//得到公钥
Key publicKey = keyPair.getPublic();
Base64.Encoder encoder = Base64.getEncoder();
String publicKeyStr = encoder.encodeToString(publicKey.getEncoded());
//得到私钥
Key privateKey = keyPair.getPrivate();
String privateKeyStr = encoder.encodeToString(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put("publicKey", publicKeyStr);
keyPairMap.put("privateKey", privateKeyStr);
return keyPairMap;
}
/**
* 公钥加密
*
* @param data
* @param publicKey
* @return
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
}
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
int maxBlock = 0;
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
} catch (Exception e) {
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
}
byte[] resultDatas = out.toByteArray();
try {
out.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resultDatas;
}
/**
* 私钥解密
*
* @param data
* @param privateKey
* @return
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
Base64.Decoder decoder = Base64.getDecoder();
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, decoder.decode(data), privateKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 得到公钥
*
* @param publicKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPublicKey getPublicKey(String publicKey) throws Exception {
//通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
Base64.Decoder decoder = Base64.getDecoder();
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decoder.decode(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
/**
* 得到私钥
*
* @param privateKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws Exception {
//通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
Base64.Decoder decoder = Base64.getDecoder();
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(decoder.decode(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
public static void main(String[] args) throws Exception {
Map<String, String> keyMap = RSAUtil.createKeys(1024);
String publicKey = keyMap.get("publicKey");
String privateKey = keyMap.get("privateKey");
System.out.println("公钥: \n\r" + publicKey);
System.out.println("私钥: \n\r" + privateKey);
System.out.println("公钥加密——私钥解密");
String str = "111";
System.out.println("\r明文:\r\n" + str);
System.out.println("\r明文大小:\r\n" + str.getBytes().length);
String encodedData = RSAUtil.publicEncrypt(str, RSAUtil.getPublicKey(publicKey));
System.out.println("密文:\r\n" + encodedData);
String decodedData = RSAUtil.privateDecrypt(encodedData, RSAUtil.getPrivateKey(privateKey));
System.out.println("解密后文字: \r\n" + decodedData);
}
}
有不懂的怎么用的可以参考main方法。
最后就是两个前端页面的代码了。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/aesview">AES对称加密</a><br>
<input type="text" id="content"/>
<input type="button" value="根据服务端公钥加密" onclick="login()"><br><br>
<hr>
<label>服务端公钥: </label>
<div id="serverPublicKey"></div>
<br>
<label>服务端秘钥:</label>
<div id="serverPrivateKey"></div>
<label>JS加密传输</label>
<div id="encryptContent"></div>
<label>解密后</label>
<div id="decryptContent"></div>
<label>Js解密</label>
<div id="decryptContent2"></div>
</body>
</html>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdn.bootcss.com/jsencrypt/2.3.1/jsencrypt.min.js"></script>
<script>
$(function () {
getKey();
})
function getKey() {
$.ajax({
url: '/getPublicKey',
method: 'get',
dataType: 'json',
success: function (res) {
if (res.code == 0) {
var key = res.data.publickey;
$("#serverPublicKey").text(key);
$("#serverPrivateKey").text(res.data.privatekey);
}
}
})
}
function login() {
var content = $('#content').val();
// 前端进行加密
var publicKey = $("#serverPublicKey").text();
var contents = encrypt(content, publicKey);
console.log(contents)
$("#encryptContent").text(contents);
// 前端进行解密
var privateKey = $("#serverPrivateKey").text();
var encryptContent = $("#encryptContent").text()
var contents2 = decrypt(encryptContent, privateKey);
console.log(contents2)
$("#decryptContent2").text(contents2);
dologin(contents)
}
function dologin(content) {
$.ajax({
url: '/login',
method: 'post',
dataType: 'json',
data: {
content: content
},
success: function (res) {
console.log(res);
$("#decryptContent").text(res.data.content)
}
})
}
/**
* 加密内容 text 公钥key
*/
function encrypt(text, key) {
// Encrypt with key...
var encryptKey = new JSEncrypt();
encryptKey.setPublicKey(key);
// return encryptKey.encrypt(text);
return encryptKey.encrypt(text);
}
/**
* 解密内容 text 密钥key
*/
function decrypt(text, key) {
console.log('秘钥: ' + key);
console.log('秘钥: ' + text);
// Encrypt with key...
var decryptor = new JSEncrypt();
// 设置密钥key
decryptor.setPrivateKey(key);
return decryptor.decrypt(text);
}
</script>
aesview.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<input type="text" id="content"/>
<input type="button" value="根据服务端公钥加密" onclick="login()">
<br>
<br>
<hr>
<label>密文:</label>
<div id="cipherText"></div>
<label>密钥:</label>
<div id="aeskey"></div>
<label>iv:</label>
<div id="iv"></div>
<label>加密传输</label>
<div id="encryptContent"></div>
<label>解密后</label>
<div id="decryptContent"></div>
<label>Js解密</label>
<div id="decryptContent2"></div>
</body>
</html>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/core.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/cipher-core.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/mode-ecb.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/aes.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/enc-base64.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
// 测试加、解密
function testAES() {
var key = "8NONwyJtHesysWpM";
var plaintText = 'ABCDEFGH'; // 明文
var encryptedData = getAesString(plaintText, key);
console.log(encryptedData);
var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedData.ciphertext);
console.log("密文: " + encryptedBase64Str + "");
console.log("解密后: " + getDAesString(encryptedData, key));
}
$(function () {
getKey();
})
function getKey() {
$.ajax({
url: '/getAesKey',
method: 'get',
dataType: 'json',
success:function (res) {
if (res.code == 0){
var key=res.data.key;
var iv= res.data.iv;
$("#aeskey").text(key);
$("#iv").text(iv);
}
}
})
}
function login() {
var content = $('#content').val();
//前端进行加密
var key =$("#aeskey").text();
var Encryptcontent = getAesString(content,key);
$("#encryptContent").text(Encryptcontent);
//前端进行解密
var decrypt= getDAesString(Encryptcontent,key);
$("#decryptContent2").text(decrypt);
dologin(Encryptcontent)
}
function dologin(content) {
$.ajax({
url: '/aes',
method: 'post',
dataType: 'json',
data: {
content: content
},
success: function (res) {
console.log(res);
$("#decryptContent").text(res.data.content)
}
})
}
function getAesString(data, key) {//加密
var key = CryptoJS.enc.Utf8.parse(key);
var encrypted = CryptoJS.AES.encrypt(data, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted; //返回的是base64格式的密文
}
function getDAesString(encrypted, key) {//解密
var key = CryptoJS.enc.Utf8.parse(key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key,
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
</script>
还有些不记得原地址,在此也感谢大佬们。