前端使用sm2公钥加密,后端golang sm2私钥解密,跨语言使用说明

前端使用sm2公钥加密,后端golang sm2私钥解密,跨语言使用说明

Golang 使用 gmsm 加/解密:

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
func TestGmsm2Encrypt(t *testing.T) {

// 原文
dataBytes := []byte("hello world")

// 生成密钥对
sm2PriKey, err := sm2.GenerateKey(nil)
if err != nil {
return
}

// 私钥 hex
s := hex.EncodeToString(sm2PriKey.D.Bytes())
fmt.Println(s)

// 公钥 hex
sm2PubKey := sm2PriKey.PublicKey
s2 := "04" + hex.EncodeToString(sm2PubKey.X.Bytes()) + hex.EncodeToString(sm2PubKey.Y.Bytes())
fmt.Println(s2)

// 公钥加密
encrypt, err := sm2.Encrypt(&sm2PubKey, dataBytes, nil, sm2.C1C3C2)
if err != nil {
return
}
fmt.Println(hex.EncodeToString(encrypt))

// 私钥解密
decrypt, err := sm2.Decrypt(sm2PriKey, encrypt, sm2.C1C3C2)
if err != nil {
return
}
fmt.Println(string(decrypt))
}

输出示例:

1
2
3
4
5
6
7
8
// 私钥
edec1100fbc83411ed1112bab763df275f91ad3140aa19ae5cc717012454fefc
// 公钥
0416c9fdfabe11ca0efe5aae03cdb46b96e39e14095e926e5f021889f79abd04631791d2dc1672bad412596d5f32a6977332f5c815bf6ca948c9f3f24999551b07
// golang 加密的密文
04f6f663b4ca467c1b0053ae6d22079ef3a9612253829eee84f32846067630aeeb95f19119a52b816ecf71ffdd9cdb68ca6fa2ab748a50acde6d9c93249288558645636ef1d77bbd32b419b87a7cd2337bb6362b6122746c0b313f461b373f7c61ea5a27b2dc2846ccd88f43
// golang 解密的明文
hello world

js 使用 sm-crypto 加解密 golang 密文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const Sm2Crypto = require("sm-crypto").sm2;

// golang 加密的密文,需要移除前面的 04 标识
let cipherText = "f6f663b4ca467c1b0053ae6d22079ef3a9612253829eee84f32846067630aeeb95f19119a52b816ecf71ffdd9cdb68ca6fa2ab748a50acde6d9c93249288558645636ef1d77bbd32b419b87a7cd2337bb6362b6122746c0b313f461b373f7c61ea5a27b2dc2846ccd88f43";
// 私钥
let privateKeyHex = "edec1100fbc83411ed1112bab763df275f91ad3140aa19ae5cc717012454fefc";
// 解密
let decryptText = Sm2Crypto.doDecrypt(cipherText, privateKeyHex, 1);
console.log(decryptText);

// 公钥
let publicKeyHex = "0416c9fdfabe11ca0efe5aae03cdb46b96e39e14095e926e5f021889f79abd04631791d2dc1672bad412596d5f32a6977332f5c815bf6ca948c9f3f24999551b07"
// 加密
let encryptText = Sm2Crypto.doEncrypt("hello world", publicKeyHex, 1);
console.log(encryptText);

输出示例:

1
2
3
4
// js 解密的明文
hello world
// js 加密的密文
17b8d0bde323c8b9bb593e0916e8f60ba2ac765fcc10ef1a88985c8a89e13bd9be256b8948761fbb8dbf531c99d62148f391f90cf1037e6d4cfb6934faed4172a37e5e4466b3a139330c9f9c5927216d2460733eedf6c2cd1ef54cf5d5e1f5b88e17c6e77a503c342d3cb6

使用 golang 解密 js 密文:

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
func TestGmsm2Decrypt(t *testing.T) {

// js 加密的密文,需要添加 04 标识
cipherBytes, _ := hex.DecodeString("0417b8d0bde323c8b9bb593e0916e8f60ba2ac765fcc10ef1a88985c8a89e13bd9be256b8948761fbb8dbf531c99d62148f391f90cf1037e6d4cfb6934faed4172a37e5e4466b3a139330c9f9c5927216d2460733eedf6c2cd1ef54cf5d5e1f5b88e17c6e77a503c342d3cb6")

// 还原私钥结构体
X, _ := hex.DecodeString("16c9fdfabe11ca0efe5aae03cdb46b96e39e14095e926e5f021889f79abd0463")
Y, _ := hex.DecodeString("1791d2dc1672bad412596d5f32a6977332f5c815bf6ca948c9f3f24999551b07")
D, _ := hex.DecodeString("edec1100fbc83411ed1112bab763df275f91ad3140aa19ae5cc717012454fefc")
pubX := new(big.Int).SetBytes(X)
pubY := new(big.Int).SetBytes(Y)
priD := new(big.Int).SetBytes(D)

sm2PriKey := &sm2.PrivateKey{
PublicKey: sm2.PublicKey{
Curve: sm2.P256Sm2(),
X: pubX,
Y: pubY,
},
D: priD,
}

// 私钥解密
decrypt, err := sm2.Decrypt(sm2PriKey, cipherBytes, sm2.C1C3C2)
if err != nil {
return
}
fmt.Println(string(decrypt))
}

输出示例:

1
hello world

golang封装

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
package sm2_tools

import (
"encoding/hex"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/tjfoc/gmsm/sm2"
"github.com/tjfoc/gmsm/x509"
)

// GenerateKey 生成密钥对
func GenerateKey() (sm2PriKeyStr string, sm2PubKeyStr string) {
// 生成密钥对
sm2PriKey, err := sm2.GenerateKey(nil)
if err != nil {
return
}
// 私钥 hex
sm2PriKeyStr = hex.EncodeToString(sm2PriKey.D.Bytes())
// 公钥 hex
sm2PubKey := sm2PriKey.PublicKey
sm2PubKeyStr = "04" + hex.EncodeToString(sm2PubKey.X.Bytes()) + hex.EncodeToString(sm2PubKey.Y.Bytes())
return
}

// DecryptFromJsWithPrivateKey DecryptFromJsWithPrivate js 加密密文,解密,js 使用sm-crypto库
func DecryptFromJsWithPrivateKey(str string, privateKey string) (decryptStr string) {
// js 加密的密文,需要添加 04 标识
str = "04" + str
cipherBytes, _ := hex.DecodeString(str)
if len(cipherBytes) < 96 {
return
}
privateK, err := x509.ReadPrivateKeyFromHex(privateKey)
if err != nil {
err = gerror.New("读取私钥失败")
return
}

// 私钥解密
decrypt, err := sm2.Decrypt(privateK, cipherBytes, sm2.C1C3C2)
if err != nil {
return
}
decryptStr = string(decrypt)
return
}

func EncryptWithPublicKey(str string, publicKey string) (encryptStr string) {
// 原文
dataBytes := []byte(str)
// 公钥 hex
sm2PubKey, err := x509.ReadPublicKeyFromHex(publicKey)
if err != nil {
err = gerror.New("读取公钥失败")
return
}

// 公钥加密
encrypt, err := sm2.Encrypt(sm2PubKey, dataBytes, nil, sm2.C1C3C2)
if err != nil {
return
}
encryptStr = hex.EncodeToString(encrypt)
return
}


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!