一、对称加密

1. AES

1.1 介绍

AES(高级加密标准)是一种对称加密算法,即加密和解密使用相同的密钥。它可以加密长度为128、192和256位的数据块,并使用128位的密钥进行加密。AES算法使用了固定的块长度和密钥长度,并且被广泛应用于许多安全协议和标准中,例如SSL/TLS、SSH、IPSec等。

在AES加密中,明文被分成128位的块,每个块使用相同的密钥进行加密。加密过程包括以下步骤:

  1. 密钥扩展:将密钥扩展为加密算法所需的轮密钥。
  2. 初始轮:将明文分成块,并与第一轮密钥进行异或。
  3. 多轮加密:将初始轮产生的结果反复进行多轮加密,每轮使用不同的轮密钥进行加密。
  4. 最终轮:在最后一轮加密中,将块进行加密,但是不再进行下一轮加密,而是直接输出密文。

1.2 加解密步骤

前端:

  1. 初始化: 引入jsencrypt库并出始化JSEncrypt对象,使用encrypt.setPublicKey()方法设置公钥,公钥是随机任意字符串 。
  2. 生成私钥和偏移量: 随机生成aes的私钥key和偏移量 iv,使用encrypt.encrypt()方法对私钥key和偏移量iv进行加密得到code,并将code传给后端, 将私钥与code存入客户端。
  3. 加密: 引入CryptoJS插件,使用CryptoJS.AES.encrypt()方法结合生成的私钥key和偏移量iv加密数据。

后端:

  1. 初始化: 使用encrypt.setPrivateKey()方法设置私钥,私钥要与前端的公钥一致。
  2. 解密code: 使用encryptor.decrypt()方法解密code得到eas的私钥key和偏移量iv。
  3. 解密数据: 引入CryptoJS插件, 使用CryptoJS.AES.decrypt()方法结合key和iv解密数据。

1.3 前端代码实现

封装加密/解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 创建key.js文件

import JSEncrypt from 'jsencrypt'
const encrypt = new JSEncrypt();
let publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeCDcnFrS7DIRbvZLHreVUzaMbAFy2DYmioxBK606urY4rVR8IgLgUhnyw2/GQ99pyr8lGtqPeOoapantw1XwEVyi74MDxs4UDL8j4OZR1Es7HVGOB0GwKWobdU9cm/1iDwGyouSmijxKyAePg6KsLNgbjDPYZRS11bYEuZ8/RLQIDAQAB';
// 设置公钥
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + publicKey + '-----END PUBLIC KEY-----')

const random = (length) => {
var str = Math.random().toString(36).substr(2);
if (str.length >= length) {
return str.substr(0, length);
}
str += random(length - str.length);
return str;
}

export const rsaEncode = (src) => {
// 加密数据
let data = encrypt.encrypt(src);
return data
};

export const getKey = () => {
// 生成私钥和偏移量
let key = { key: random(16), iv: random(16) };
// 对私钥和偏移量加密
let code = rsaEncode(key.key + ',' + key.iv);
window.codeArr = window.codeArr || {};
// 存入客户端
codeArr[code] = key;
return {
key, code
}
};

export const getAesKey = (aes) => {
let key = JSON.parse(JSON.stringify(codeArr[aes]));
// 从客户端获取到 key
delete codeArr[aes];
return key
};

window.getKey = getKey
window.rsaEncode = rsaEncode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 创建 encrypt.js 文件
import CryptoJS from 'crypto-js';

// ------------AES 加密-------------
function getAesString(data, key, iv) {
let keys = CryptoJS.enc.Utf8.parse(key)
let vis = CryptoJS.enc.Utf8.parse(iv)
let encrypt = CryptoJS.AES.encrypt(data, keys, {
iv: vis, //iv偏移量 CBC需加偏移量
mode: CryptoJS.mode.CBC, //CBC模式
padding: CryptoJS.pad.Pkcs7 //padding处理
});
return encrypt.toString(); //加密完成后,转换成字符串
}


// ------------AES 解密-------------
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 decrypted.toString(CryptoJS.enc.Utf8);
}

// AES 对称秘钥加密
const aes = {
en: (data, key) => getAesString(data, key.key, key.iv),
de: (data, key) => getDAesString(data, key.key, key.iv)
};

export { aes };

二、非对称加密

1. RSA

1.1 介绍

RSA加密算法是一种非对称加密算法,RSA加密使用了”一对”密钥.分别是公钥和私钥,这个公钥和私钥其实就是一组数字,其二进制位长度可以是1024位或者2048位,长度越长其加密强度越大。

1.2 加解密

  1. 使用公钥加密的数据,利用私钥进行解密
  2. 使用私钥加密的数据,利用公钥进行解密

1.3 前端代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import JSEncrypt from 'jsencrypt'

// rsa加密
var encryptor = new JSEncrypt() // 创建加密对象实例
//之前OpenssL生成的公钥,复制的时候要小心不要有空格
var pubKey = '-----BEGIN PUBLIC KEY-----MIG...QIDAQAB-----END PUBLIC KEY-----'
encryptor.setPublicKey(pubKey)//设置公钥
var rsaPassWord = encryptor.encrypt('要加密的内容') // 对内容进行加密

// rsa解密
var decrypt = new JSEncrypt()//创建解密对象实例
//之前OpenssL生成的秘钥
var priKey = '-----BEGIN RSA PRIVATE KEY-----MIICX...mJLH5gbdvJJmCWRk=-----END RSA PRIVATE KEY----'
decrypt.setPrivateKey(priKey)//设置秘钥
var uncrypted = decrypt.decrypt(encrypted)//解密之前拿公钥加密的内容

三、哈希算法

1. MD5

1.1 介绍

MD5加密算法,其全称是Message-Digest Algorithm 5,通常被称为信息摘要算法,所谓的信息摘要就是把明文内容按一定规则生成一段哈希(hash)值,即得到这段明文内容的信息摘要。利用MD5可以基于任意长度的明文字符串生成128位的哈希值,结果唯一且不可逆,因此MD5经常被用于防止信息被篡改、数字签名、以及对明文进行加密等场景。

1.2 特性

压缩性:任意长度的数据,算出的MD5值长度都是固定的。

容易计算:从原数据计算出MD5值很容易。

抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

弱抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

从技术的角度来说,MD5真的很安全,因为MD5本身是不可逆的,因此没法解密,除了撞库这样的一个方式。

1.3 加解密

MD5算法加密的过程分为三步:处理原文,设置初始值,加密运算。

1.4 前端实现

md5.js共有md5的6种加密方法:

1
2
3
4
5
6
7
8
9
var code = "123456";
var username = "123456";
var password = "123456";
var str1 = hex_md5("123456"); // e10adc3949ba59abbe56e057f20f883e 我们常用的是这种
var str2 = b64_md5("123456");
var str3 = str_md5("123456");
var str4 = hex_hmac_md5(code,code); // 30ce71a73bdd908c3955a90e8f7429ef
var str5 = b64_hmac_md5(username,username); // MM5xpzvdkIw5VakOj3Qp7w
var str6 = str_hmac_md5(password,password);

2. SHA-3

2.1 介绍

SHA-3 算法是第三代标准的哈希函数,基于 Keccak 算法实现。与之前的哈希算法有所不同,SHA-3 算法是基于置换 ( permutation-based ) 的加密函数。

2.2 原理

哈希算法是信息安全领域重要的组成部分,主要包括:

1、生成和验证数字签名

2、密钥导出 (key derivation)

3、伪随机位生成 (pseudorandom bit generation)

2.2 前端实现

1
2
3
4
5
6
7
8
9
10
11
12
13
import CryptoJS from "crypto-js";

//加密224位
CryptoJS.SHA3('六月初博客',{ outputLength: 224 })

// 加密256位
CryptoJS.SHA3('六月初博客站',{ outputLength: 256})

//加密384位
CryptoJS.SHA3('六月初工具',{ outputLength: 384})

// 加密512位
CryptoJS.SHA3('六月初工具站',{ outputLength: 512})