文章目录
- 前言
- 一、什么是对称加密和非对称加密?
- 1.1、对称加密介绍
- 1.2、非对称加密介绍
- 二、RSA非对称加密前后端实现
- 2.1、前端实现rsa
- 2.2、后端实现rsa解密
- 三、AES加密前后端实现
- 3.1、AES前端实现
- 3.2、AES后端解密实现(2种方式)
前言
项目中正好遇到给私密参数加密的步骤,特意学习了非对称加密和对称加密的2个个例。
一、什么是对称加密和非对称加密?
1.1、对称加密介绍
对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。
对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。
对称加密的一大缺点是密钥的管理与分配,换句话说,如何把密钥发送到需要解密你的消息的人的手里是一个问题。在发送密钥的过程中,密钥有很大的风险会被黑客们拦截。现实中通常的做法是将对称加密的密钥进行非对称加密,然后传送给需要它的人。
对称加密,加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦,常见的aes。
1.2、非对称加密介绍
非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥(public key)和私钥(private key)。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥,公钥加密,私钥解密。 非对称算法,加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。常见的非对称加密算法为RSA、ECC和EIGamal
AES加密原理RAS加密原理
二、RSA非对称加密前后端实现
2.1、前端实现rsa
1、安装jsencrypt,执行以下命令
npm install jsencrypt --save-dev
2 、安装encryptlong,执行以下命令
npm i encryptlong -S
3、生成公钥私钥 准备publicKey(公钥)&& privateKey(私钥)在线生成公钥私钥网址
4、前端代码实现
/* 产引入jsencrypt实现数据RSA加密 */
import JSEncrypt from 'jsencrypt' // 处理长文本数据时报错 jsencrypt.js Message too long for RSA
/* 产引入encryptlong实现数据RSA加密 */
import Encrypt from 'encryptlong' // encryptlong是基于jsencrypt扩展的长文本分段加解密功能。
// 密钥对生成 http://web.chacuo.net/netrsakeypair
// 公钥key
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD\n' +
'2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ=='
// 私钥key
const privateKey = 'MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8\n' +
'mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9p\n' +
'B6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue\n' +
'/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZ\n' +
'UBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6\n' +
'vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha\n' +
'4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3\n' +
'tTbklZkD2A=='
export default {
/* JSEncrypt加密 */
rsaPublicData(data) {
var jsencrypt = new JSEncrypt()
jsencrypt.setPublicKey(publicKey)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data)
return result
},
/* JSEncrypt解密 */
rsaPrivateData(data) {
var jsencrypt = new JSEncrypt()
jsencrypt.setPrivateKey(privateKey)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data)
return result
},
/* 加密 */
encrypt(data) {
const PUBLIC_KEY = publicKey
var encryptor = new Encrypt()
encryptor.setPublicKey(PUBLIC_KEY)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
const result = encryptor.encryptLong(data)
return result
},
/* 解密 - PRIVATE_KEY - 验证 */
decrypt(data) {
const PRIVATE_KEY = privateKey
var encryptor = new Encrypt()
encryptor.setPrivateKey(PRIVATE_KEY)
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = encryptor.decryptLong(data)
return result
}
}
4、全局引用
import Rsa from "@/utils/rsa.js"
Vue.prototype.Rsa = Rsa //
5、在*.vue 页面使用RSA加解,全局使用
this.Rsa.方法名
参考前端实现
2.2、后端实现rsa解密
1、引入hutool依赖
<!-- 工具类 参考https://hutool.cn/docs-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.10</version>
</dependency>
2、方法
private String decodeStr(String encodeStr) {
try {
String privateKey = ResourceUtil.readUtf8Str(PRIVATE_KEY_LOCATION);
RSA rsa = new RSA(privateKey, null);
byte[] aByte = SecureUtil.decode(encodeStr);
byte[] decrypt = rsa.decrypt(aByte, KeyType.PrivateKey);
return StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
} catch (Exception e) {
logger.error("RSA私钥解密失败!", e);
throw new BadCredentialsException(encodeStr);
}
}
3、hutool加密解密使用参考
hutools地址
三、AES加密前后端实现
3.1、AES前端实现
1、下载依赖
下载crypto-js
npm install crypto-js --save
2、代码具体使用
import CryptoJS from 'crypto-js'
const key = 'f4k9f5w7f8g4er26' //前后端使用同意秘钥
// 偏移量 16位(不可随意修改,否则前后端加密解密可能失败)
const iv = '0000000000000000'
export function encrypt(data) {
return CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(data), CryptoJS.enc.Utf8.parse(key), {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
.toString()
}
export function decrypt(data) {
const decrypted = CryptoJS.AES.decrypt(data, CryptoJS.enc.Utf8.parse(key), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8).toString()
}
3、全局引用同上rsa
3.2、AES后端解密实现(2种方式)
1、使用hutool工具类(使用hutool相对更加方便)
String content = "test中文";
//随机生成密钥
byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
//构建
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
//加密
byte[] encrypt = aes.encrypt(content);
//解密
byte[] decrypt = aes.decrypt(encrypt);
//加密为16进制表示
String encryptHex = aes.encryptHex(content);
//解密为字符串
String decryptStr = aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
2、使用commons-code依赖的工具 引入依赖
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
aes工具类
public class Encrypt {
//--------------AES---------------
private static final String KEY = "f4k9f5w7f8g4er26"; // 密匙,必须16位
private static final String ENCODING = "UTF-8"; // 编码
private static final String ALGORITHM = "AES"; //算法
private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; // 默认的加密算法,ECB模式
/**
* AES加密
* @param data
* @return String
*/
public static String AESencrypt(String data) throws Exception
{
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,new SecretKeySpec(KEY.getBytes(),"AES"));
byte[] b = cipher.doFinal(data.getBytes("utf-8"));
//采用base64算法进行转码,避免出现中文乱码
return Base64.encodeBase64String(b);
}
/**
* AES解密
* @param data
* @return String
*/
public static String AESdecrypt(String data) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY.getBytes(), "AES"));
byte[] b = cipher.doFinal(Base64.decodeBase64(data));
//采用base64算法进行转码,避免出现中文乱码
return new String(b);
}
public static void main(String[] args) throws Exception {
String mi = Encrypt.AESencrypt("111111");
System.out.println(mi);
}
}