加解密

加解密

加密类型

对称加密:密钥-都用于加解密

非对称加密:公钥进行加密,私钥进行解密

加密算法

SM2:这是一种基于椭圆曲线的非对称加密算法。用于加密数据时,使用公钥进行加密,私钥进行解密。代码中生成了一个密钥对,然后用公钥对原始数据进行加密。

用途:一般用于加密较小的数据,或用于加密对称加密的密钥。

SM4:这是一种对称加密算法,与AES类似。你这里使用了CBC模式,需要一个初始化向量(IV)来增加加密的强度。加密后的数据以base64形式输出。

用途:常用于大数据量的加密,比如文件加密或传输过程中加密整个消息体。

对称加密

SM4加密,自定义config密钥

1
2
3
4
5
6
export default {
sm4Key: "Wc8QoMm0EoyDuTh5",
sm4Iv: "wjTAgXcz_O=It9Zo",
sm4Mode: "cbc",
sm4CipherType: "base64",
}
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
import { SM4 } from 'gm-crypto';

// 加密

const SM4Encrypt = function(originalData: string): string {
const encryptData = SM4.encrypt(originalData, stringToHex(config.sm4Key), {
mode: SM4.constants.CBC, // 加密的方式有两种,ecb和cbc两种,这里使用的是cbc,cbc模式还要加一个iv的参数,ecb不用
iv: stringToHex(config.sm4Iv), //iv是cbc模式的第二个参数,也需要跟后端配置的一致
inputEncoding: 'utf8',
outputEncoding: 'base64'
})
return encryptData;
}


// 解密
const SM4Decrypt = function(encryptedData: string): string {
const decryptedData = SM4.decrypt(encryptedData, stringToHex(config.sm4Key), {
mode: SM4.constants.CBC, // 解密时使用与加密时相同的模式
iv: stringToHex(config.sm4Iv), // 使用相同的IV
inputEncoding: 'base64', // 加密数据是Base64编码
outputEncoding: 'utf8' // 解密后的数据以UTF-8字符串形式输出
});
return decryptedData;
}


// SM4加密解密key需要转为32位16进制数
const stringToHex = function(str) {
let val = ''
for (let i = 0; i < str.length; i++) {
val += str.charCodeAt(i).toString(16)
}
return val
}

非对称加密

SM2加密-获取密钥对践中的密钥管理

  • 密钥对生成后,私钥的管理非常关键。前端生成的私钥通常不在客户端长期存储,而是临时使用后销毁。
  • 公钥的管理相对简单,可以通过服务器下发或直接嵌入代码中。但要确保公钥未被篡改。
  • 在实际应用中,密钥对通常由后端生成并管理,前端仅使用公钥进行加密操作。私钥仅在后端用于解密或签名操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { SM2 } from 'gm-crypto';

// 生成密钥对
const { publicKey, privateKey } = SM2.generateKeyPair();

// 打印公钥和私钥
console.log("Public Key:", publicKey);
console.log("Private Key:", privateKey);

// 使用公钥加密数据
const originalData = "Hello, SM2!";
const encryptedData = SM2.encrypt(originalData, publicKey, {
inputEncoding: 'utf8',
outputEncoding: 'base64'
});

console.log("Encrypted Data:", encryptedData);

完整的例子

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

import { SM4, SM3, SM2 } from 'gm-crypto'
import config from '/@/common/config'

// sm2非对称
const SM2Encrypt = function(originalData: string): string {
const { publicKey, privateKey } = SM2.generateKeyPair();

const encrytedData = SM2.encrypt(originalData, publicKey, {
inputEncoding: 'utf8',
outputEncoding: 'base64'
})
return encrytedData;
}

// sm4对称-加密

const SM4Encrypt = function(originalData: string): string {
const encryptData = SM4.encrypt(originalData, stringToHex(config.sm4Key), {
mode: SM4.constants.CBC, // 加密的方式有两种,ecb和cbc两种,这里使用的是cbc,cbc模式还要加一个iv的参数,ecb不用
iv: stringToHex(config.sm4Iv), //iv是cbc模式的第二个参数,也需要跟后端配置的一致
inputEncoding: 'utf8',
outputEncoding: 'base64'
})
return encryptData;
}


// sm4对称-解密
const SM4Decrypt = function(encryptedData: string): string {
const decryptedData = SM4.decrypt(encryptedData, stringToHex(config.sm4Key), {
mode: SM4.constants.CBC, // 解密时使用与加密时相同的模式
iv: stringToHex(config.sm4Iv), // 使用相同的IV
inputEncoding: 'base64', // 加密数据是Base64编码
outputEncoding: 'utf8' // 解密后的数据以UTF-8字符串形式输出
});
return decryptedData;
}


// SM4加密解密key需要转为32位16进制数
const stringToHex = function(str) {
let val = ''
for (let i = 0; i < str.length; i++) {
val += str.charCodeAt(i).toString(16)
}
return val
}

export default {
SM2Encrypt,
SM4Encrypt,
SM4Decrypt
stringToHex
}