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 }