migu_server/tools/sm4.go
2024-10-18 23:46:54 +08:00

80 lines
1.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tools
import (
"bytes"
"crypto/cipher"
"encoding/hex"
"github.com/tjfoc/gmsm/sm4"
)
// ECB 模式加密结构体
type ecb struct {
b cipher.Block
blockSize int
}
// 实现 ECB 加密
type ecbEncrypter ecb
func newECB(b cipher.Block) *ecb {
return &ecb{
b: b,
blockSize: b.BlockSize(),
}
}
func newECBEncrypter(b cipher.Block) cipher.BlockMode {
return (*ecbEncrypter)(newECB(b))
}
func (x *ecbEncrypter) BlockSize() int {
return x.blockSize
}
func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.b.Encrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
// PKCS5Padding 补全填充
func PKCS5Padding(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padText...)
}
// SM4Encrypt 使用 SM4 对手机号进行加密ECB 模式)
func SM4Encrypt(key, plaintext string) (string, error) {
// 将秘钥和明文转换为字节数组
keyBytes := []byte(key)
plaintextBytes := []byte(plaintext)
// 创建SM4的加密block
block, err := sm4.NewCipher(keyBytes)
if err != nil {
return "", err
}
// 填充明文到块大小SM4块大小为16字节
paddingText := PKCS5Padding(plaintextBytes, block.BlockSize())
// 创建 ECB 加密器
mode := newECBEncrypter(block)
// 加密
ciphertext := make([]byte, len(paddingText))
mode.CryptBlocks(ciphertext, paddingText)
// 将加密后的数据转换为hex编码
return hex.EncodeToString(ciphertext), nil
}