数据加密方式有:

单向加密、对称加密、非对称加密、加密盐、散列函数、数字签名。

1、单向加密

  • 单向加密通过对数据进行摘要计算生成密文,密文不可逆推还原。只能加密,不能解密,常用于提取数据的指纹信息以此来验证数据的完整性。但是会引发雪崩效应(雪崩效应就是一种不稳定的平衡状态也是加密算法的一种特征,它指明文或密钥的少量变化会引起密文的很大变化,就像雪崩前,山上看上去很平静,但是只要有一点问题,就会造成一片大崩溃。 可以用在很多场合对于Hash码,雪崩效应是指少量消息位的变化会引起信息摘要的许多位变化。)

算法代表:Base64,MD5,SHA。

1. Base64加密

Base64是一种用来将二进制数据编码为可读文本形式的编码规范。在这个页面中,当用户点击“base64加密”按钮时,会调用一个JavaScript函数fn1(),该函数使用了window.btoa()方法进行Base64加密操作,并使用window.atob()方法进行解密操作。具体实现如下:

1
2
3
4
5
6
7
8
9
// base64加密
var fn1=()=>{
// 加密
var str = window.btoa('123564896514')
console.log('加密后',str);
// 解密
var str2 = window.atob(str);
console.log('解密后',str2);
}

window.btoa()方法接受一个字符串作为参数,返回该字符串的Base64编码结果。window.atob()方法接受一个Base64编码的字符串作为参数,返回该编码的原始字符串。

2. MD5加密

MD5是一种常用的密码散列函数,通常用于对一段数据产生唯一的“指纹”,以便于验证数据的完整性和一致性。在这个页面中,当用户点击“MD5加密”按钮时,会调用一个JavaScript函数fn2(),该函数使用了md5.js库文件中提供的md5()方法进行MD5加密操作。具体实现如下:

1
2
3
4
5
6
7
// MD5加密(不可逆的) 密码散列函数  需要引入https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js 这个js文件
var fn2=()=>{
// 加密
var str = '123'
var str2 = md5(str)
console.log('加密后',str2);
}

md5()方法接受一个字符串作为参数,返回该字符串的MD5编码结果。

3. SHA-1加密

SHA-1是一种常用的密码散列函数,类似于MD5,但具有更高的安全性。在这个页面中,当用户点击“sha-1.js加密”按钮时,会调用一个JavaScript函数fn3(),该函数使用了sha1.js库文件中提供的sha1()方法进行SHA-1加密操作。具体实现如下:

1
2
3
4
5
6
7
// sha-1加密(不可逆) 是一种数加密算法  需要引入https://cdn.bootcss.com/js-sha1/0.6.0/sha1.js  
var fn3=()=>{
// 加密
var str = '123'
var str2 = sha1(str)
console.log('加密后',str2);
}

sha1()方法接受一个字符串作为参数,返回该字符串的SHA-1编码结果。

2、对称加密

  • 对称加密的加密和解密是使用同一个密钥;加密和解密的速度比较快,效率比较高;但是密钥传输过程不安全,容易破解,而且密钥管理也比较麻烦。

算法代表:DES,3DES,AES,IDEA,RC4,RC5。

对称加密可以分为两类:序列密码和分组密码

3. AES加密

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 导入必要的库
const CryptoJS = require('crypto-js');

// const key = '1234567890abcdef'; // 密钥必须为 8/16/32 位
// const message = 'hello';

// 定义 AES 加密函数
export function encryptAES(message, key) {
const encrypted = CryptoJS.AES.encrypt(
message,
CryptoJS.enc.Utf8.parse(key),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString();
return encrypted;
}

// 定义 AES 解密函数
export function decryptAES(encrypted, key) {
const decrypted = CryptoJS.AES.decrypt(
encrypted,
CryptoJS.enc.Utf8.parse(key),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString(CryptoJS.enc.Utf8);
return decrypted;
}


// ---- 本地存储 ----

// 存储数据时进行加密,并使用不同的键
export function saveData(key, data) {
const encryptedData = encryptAES(JSON.stringify(data), '1234567890abcdef');
localStorage.setItem(key, encryptedData);
}

// 获取数据时进行解密
export function getData(key) {
const encryptedData = localStorage.getItem(key);
if (encryptedData) {
const decryptedData = decryptAES(encryptedData, '1234567890abcdef');
return JSON.parse(decryptedData);
}
return null;
}




// ---- 会话存储 ----

// 存储数据时进行加密,并使用不同的键
export function saveSessionData(key, data) {
const encryptedData = encryptAES(JSON.stringify(data), '1234567890abcdef');
sessionStorage.setItem(key, encryptedData);
}

// 获取数据时进行解密
export function getSessionData(key) {
const encryptedData = sessionStorage.getItem(key);
if (encryptedData) {
const decryptedData = decryptAES(encryptedData, '1234567890abcdef');
return JSON.parse(decryptedData);
}
return null;
}

2.1、序列密码

  • 从概念上讲,序列密码(stream cipher)的操作过程与我们想象中加密的过程一致。将1字节的明文输入加密算法,就得到1字节的密文输出。在对端则进行相反的过程。整个过程持续重复,直到所有数据处理完成。因为这种思路比较简单,序列密码绝不能第二次使用相同的密钥。这是因为在实际使用中,攻击者知道或者可以预测特定区域的明文(请思考加密HTTP请求的情景;许多请求的请求方法、协议版本、请求头名称都是一样的)当你知道明文,又观察到密文时,就可以解析一部分密钥序列。如果使用了相同的密钥,那么就可以解密后续的部分密文。为了解这个问题,序列密码都与从长期密钥中提取出来的一次性密钥一同使用。

2.2、分组密码

  • 分组密码(block cipher)每次加密一整块数据,并且现代的分组密码倾向于使用128位(16字节)大小的块。一种分组密码就是一个变换函数:接受输入并生成看似杂乱无章的输出。只要使用相同的密钥,每一个可能的输入组合都有唯一的输出。

  • 我们可以理解为更高级的对称加密算法。这种加密算法也是非常常见,例如AES加密,有128位、192位和256位的加密强度。在现在的系统对接时,AES加密非常常见。

3、非对称加密

  • 相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能解密。这两个密钥是数学相关,用某用户密钥加密后的密文,只能使用该用户的加密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个密钥性质。这里把公开的密钥为公钥,不公开的密钥为私钥。

算法代表:RSA,DSA。