ymt/utils/sm/sm4.go

78 lines
1.7 KiB
Go

package sm
import (
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"github.com/tjfoc/gmsm/sm4"
)
func GenerateSM4Key() (string, error) {
key := make([]byte, sm4.BlockSize)
_, err := rand.Read(key)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(key), nil
}
func Encode(key string, plaintextBytes []byte) (string, error) {
d, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return "", err
}
cipherBlock, err := sm4.NewCipher(d)
if err != nil {
return "", err
}
blockSize := cipherBlock.BlockSize()
iv := make([]byte, blockSize)
for i := 0; i < blockSize; i++ {
iv[i] = 0
}
blockMode := cipher.NewCBCEncrypter(cipherBlock, iv)
padding := blockSize - len(plaintextBytes)%blockSize
for i := 0; i < padding; i++ {
plaintextBytes = append(plaintextBytes, byte(padding))
}
cipherText := make([]byte, len(plaintextBytes))
blockMode.CryptBlocks(cipherText, plaintextBytes)
return base64.StdEncoding.EncodeToString(cipherText), nil
}
func Decode(key, ciphertext string) (string, error) {
d, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return "", err
}
cipherBlock, err := sm4.NewCipher(d)
if err != nil {
return "", err
}
blockSize := cipherBlock.BlockSize()
iv := make([]byte, blockSize)
for i := 0; i < blockSize; i++ {
iv[i] = 0
}
cipherTextBytes, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return "", err
}
plainText := make([]byte, len(cipherTextBytes))
blockMode := cipher.NewCBCDecrypter(cipherBlock, iv)
blockMode.CryptBlocks(plainText, cipherTextBytes)
plainTextLen := len(plainText)
padding := int(plainText[plainTextLen-1])
buff := plainText[:plainTextLen-padding]
return string(buff), nil
}