78 lines
1.7 KiB
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
|
|
}
|