1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-09 07:02:29 +08:00

Feat/encryption for sm2 sm3 sm4 (#343)

* feat: add ContainAny

* feat:encryption adds support for SM2, SM3, and SM4 #131

* doc: add docment for SM2, SM3, and SM4 #131

---------

Co-authored-by: Jiawen <im@linjiawen.com>
This commit is contained in:
Javen
2025-11-07 19:17:55 +08:00
committed by GitHub
parent 5c13fd4f2f
commit 0851b68b83
9 changed files with 1583 additions and 2 deletions

View File

@@ -1,6 +1,6 @@
# Cryptor
cryptor 包包含数据加密和解密功能。支持 base64, md5, hmac, hash, aes, des, rsa。
cryptor 包包含数据加密和解密功能。支持 base64, md5, hmac, hash, aes, des, rsa, sm2, sm3, sm4
<div STYLE="page-break-after: always;"></div>
@@ -74,6 +74,14 @@ import (
- [RsaDecryptOAEP](#RsaDecryptOAEP)
- [RsaSign](#RsaSign)
- [RsaVerifySign](#RsaVerifySign)
- [Sm3](#Sm3)
- [Sm4EcbEncrypt](#Sm4EcbEncrypt)
- [Sm4EcbDecrypt](#Sm4EcbDecrypt)
- [Sm4CbcEncrypt](#Sm4CbcEncrypt)
- [Sm4CbcDecrypt](#Sm4CbcDecrypt)
- [GenerateSm2Key](#GenerateSm2Key)
- [Sm2Encrypt](#Sm2Encrypt)
- [Sm2Decrypt](#Sm2Decrypt)
<div STYLE="page-break-after: always;"></div>
@@ -1829,3 +1837,279 @@ func main() {
}
}
```
### <span id="Sm3">Sm3</span>
<p>计算 SM3 哈希值国密SM3密码杂凑算法。SM3 是中国国家密码管理局发布的密码杂凑算法,用于替代 MD5/SHA-1/SHA-2 等国际算法。</p>
<b>函数签名:</b>
```go
func Sm3(data []byte) []byte
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/zDAQpteAiOc)</span></b>
```go
package main
import (
"encoding/hex"
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
data := []byte("hello world")
hash := cryptor.Sm3(data)
fmt.Println(hex.EncodeToString(hash))
// Output:
// 44f0061e69fa6fdfc290c494654a05dc0c053da7e5c52b84ef93a9d67d3fff88
}
```
### <span id="Sm4EcbEncrypt">Sm4EcbEncrypt</span>
<p>使用 SM4 ECB 模式加密数据国密SM4分组密码算法。密钥长度必须为 16 字节。</p>
<b>函数签名:</b>
```go
func Sm4EcbEncrypt(data, key []byte) []byte
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/l5IQxYuuaED)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef") // 16 bytes key
plaintext := []byte("hello world")
encrypted := cryptor.Sm4EcbEncrypt(plaintext, key)
decrypted := cryptor.Sm4EcbDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm4EcbDecrypt">Sm4EcbDecrypt</span>
<p>使用 SM4 ECB 模式解密数据。密钥长度必须为 16 字节。</p>
<b>函数签名:</b>
```go
func Sm4EcbDecrypt(encrypted, key []byte) []byte
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/l5IQxYuuaED)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef")
plaintext := []byte("hello world")
encrypted := cryptor.Sm4EcbEncrypt(plaintext, key)
decrypted := cryptor.Sm4EcbDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm4CbcEncrypt">Sm4CbcEncrypt</span>
<p>使用 SM4 CBC 模式加密数据。密钥长度必须为 16 字节。返回的密文包含 IV前 16 字节)。</p>
<b>函数签名:</b>
```go
func Sm4CbcEncrypt(data, key []byte) []byte
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/65Q6iYhLRTa)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef")
plaintext := []byte("hello world")
encrypted := cryptor.Sm4CbcEncrypt(plaintext, key)
decrypted := cryptor.Sm4CbcDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm4CbcDecrypt">Sm4CbcDecrypt</span>
<p>使用 SM4 CBC 模式解密数据。密钥长度必须为 16 字节。密文应包含 IV前 16 字节)。</p>
<b>函数签名:</b>
```go
func Sm4CbcDecrypt(encrypted, key []byte) []byte
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/65Q6iYhLRTa)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef")
plaintext := []byte("hello world")
encrypted := cryptor.Sm4CbcEncrypt(plaintext, key)
decrypted := cryptor.Sm4CbcDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="GenerateSm2Key">GenerateSm2Key</span>
<p>生成 SM2 密钥对国密SM2椭圆曲线公钥密码算法。SM2 是基于椭圆曲线的非对称加密算法。</p>
<b>函数签名:</b>
```go
func GenerateSm2Key() (*Sm2PrivateKey, error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/bKYMqRLvIx3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
privateKey, err := cryptor.GenerateSm2Key()
if err != nil {
return
}
plaintext := []byte("hello world")
ciphertext, _ := cryptor.Sm2Encrypt(&privateKey.PublicKey, plaintext)
decrypted, _ := cryptor.Sm2Decrypt(privateKey, ciphertext)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm2Encrypt">Sm2Encrypt</span>
<p>使用 SM2 公钥加密数据。返回的密文格式为C1(65字节) || C3(32字节) || C2(明文长度)。</p>
<b>函数签名:</b>
```go
func Sm2Encrypt(pub *Sm2PublicKey, plaintext []byte) ([]byte, error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/bKYMqRLvIx3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
privateKey, _ := cryptor.GenerateSm2Key()
plaintext := []byte("hello world")
ciphertext, _ := cryptor.Sm2Encrypt(&privateKey.PublicKey, plaintext)
decrypted, _ := cryptor.Sm2Decrypt(privateKey, ciphertext)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm2Decrypt">Sm2Decrypt</span>
<p>使用 SM2 私钥解密数据。密文格式应为C1(65字节) || C3(32字节) || C2(明文长度)。</p>
<b>函数签名:</b>
```go
func Sm2Decrypt(priv *Sm2PrivateKey, ciphertext []byte) ([]byte, error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/bKYMqRLvIx3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
privateKey, _ := cryptor.GenerateSm2Key()
plaintext := []byte("hello world")
ciphertext, _ := cryptor.Sm2Encrypt(&privateKey.PublicKey, plaintext)
decrypted, _ := cryptor.Sm2Decrypt(privateKey, ciphertext)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```

View File

@@ -1,6 +1,6 @@
# Cryptor
Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa.
Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa, sm2, sm3, sm4.
<div STYLE="page-break-after: always;"></div>
@@ -76,6 +76,14 @@ import (
- [RsaDecryptOAEP](#RsaDecryptOAEP)
- [RsaSign](#RsaSign)
- [RsaVerifySign](#RsaVerifySign)
- [Sm3](#Sm3)
- [Sm4EcbEncrypt](#Sm4EcbEncrypt)
- [Sm4EcbDecrypt](#Sm4EcbDecrypt)
- [Sm4CbcEncrypt](#Sm4CbcEncrypt)
- [Sm4CbcDecrypt](#Sm4CbcDecrypt)
- [GenerateSm2Key](#GenerateSm2Key)
- [Sm2Encrypt](#Sm2Encrypt)
- [Sm2Decrypt](#Sm2Decrypt)
<div STYLE="page-break-after: always;"></div>
@@ -1831,3 +1839,278 @@ func main() {
}
}
```
### <span id="Sm3">Sm3</span>
<p>Calculate SM3 hash (Chinese National Cryptography SM3 Hash Algorithm). SM3 is a cryptographic hash algorithm published by the Chinese State Cryptography Administration, designed to replace MD5/SHA-1/SHA-2.</p>
<b>Signature:</b>
```go
func Sm3(data []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/zDAQpteAiOc)</span></b>
```go
package main
import (
"encoding/hex"
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
data := []byte("hello world")
hash := cryptor.Sm3(data)
fmt.Println(hex.EncodeToString(hash))
// Output:
// 44f0061e69fa6fdfc290c494654a05dc0c053da7e5c52b84ef93a9d67d3fff88
}
```
### <span id="Sm4EcbEncrypt">Sm4EcbEncrypt</span>
<p>Encrypt data using SM4 ECB mode (Chinese National Cryptography SM4 Block Cipher Algorithm). Key length must be 16 bytes.</p>
<b>Signature:</b>
```go
func Sm4EcbEncrypt(data, key []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/l5IQxYuuaED)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef") // 16 bytes key
plaintext := []byte("hello world")
encrypted := cryptor.Sm4EcbEncrypt(plaintext, key)
decrypted := cryptor.Sm4EcbDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm4EcbDecrypt">Sm4EcbDecrypt</span>
<p>Decrypt data using SM4 ECB mode. Key length must be 16 bytes.</p>
<b>Signature:</b>
```go
func Sm4EcbDecrypt(encrypted, key []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/l5IQxYuuaED)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef")
plaintext := []byte("hello world")
encrypted := cryptor.Sm4EcbEncrypt(plaintext, key)
decrypted := cryptor.Sm4EcbDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm4CbcEncrypt">Sm4CbcEncrypt</span>
<p>Encrypt data using SM4 CBC mode. Key length must be 16 bytes. The returned ciphertext contains IV (first 16 bytes).</p>
<b>Signature:</b>
```go
func Sm4CbcEncrypt(data, key []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/65Q6iYhLRTa)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef")
plaintext := []byte("hello world")
encrypted := cryptor.Sm4CbcEncrypt(plaintext, key)
decrypted := cryptor.Sm4CbcDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm4CbcDecrypt">Sm4CbcDecrypt</span>
<p>Decrypt data using SM4 CBC mode. Key length must be 16 bytes. The ciphertext should contain IV (first 16 bytes).</p>
<b>Signature:</b>
```go
func Sm4CbcDecrypt(encrypted, key []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/65Q6iYhLRTa)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
key := []byte("1234567890abcdef")
plaintext := []byte("hello world")
encrypted := cryptor.Sm4CbcEncrypt(plaintext, key)
decrypted := cryptor.Sm4CbcDecrypt(encrypted, key)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="GenerateSm2Key">GenerateSm2Key</span>
<p>Generate SM2 key pair (Chinese National Cryptography SM2 Elliptic Curve Public Key Algorithm). SM2 is an asymmetric encryption algorithm based on elliptic curve cryptography.</p>
<b>Signature:</b>
```go
func GenerateSm2Key() (*Sm2PrivateKey, error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/bKYMqRLvIx3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
privateKey, err := cryptor.GenerateSm2Key()
if err != nil {
return
}
plaintext := []byte("hello world")
ciphertext, _ := cryptor.Sm2Encrypt(&privateKey.PublicKey, plaintext)
decrypted, _ := cryptor.Sm2Decrypt(privateKey, ciphertext)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm2Encrypt">Sm2Encrypt</span>
<p>Encrypt data using SM2 public key. The returned ciphertext format is: C1(65 bytes) || C3(32 bytes) || C2(plaintext length).</p>
<b>Signature:</b>
```go
func Sm2Encrypt(pub *Sm2PublicKey, plaintext []byte) ([]byte, error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/bKYMqRLvIx3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
privateKey, _ := cryptor.GenerateSm2Key()
plaintext := []byte("hello world")
ciphertext, _ := cryptor.Sm2Encrypt(&privateKey.PublicKey, plaintext)
decrypted, _ := cryptor.Sm2Decrypt(privateKey, ciphertext)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="Sm2Decrypt">Sm2Decrypt</span>
<p>Decrypt data using SM2 private key. The ciphertext format should be: C1(65 bytes) || C3(32 bytes) || C2(plaintext length).</p>
<b>Signature:</b>
```go
func Sm2Decrypt(priv *Sm2PrivateKey, ciphertext []byte) ([]byte, error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/bKYMqRLvIx3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
privateKey, _ := cryptor.GenerateSm2Key()
plaintext := []byte("hello world")
ciphertext, _ := cryptor.Sm2Encrypt(&privateKey.PublicKey, plaintext)
decrypted, _ := cryptor.Sm2Decrypt(privateKey, ciphertext)
fmt.Println(string(decrypted))
// Output:
// hello world
}
```