You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
3.7 KiB
155 lines
3.7 KiB
package publicmethod
|
|
|
|
import (
|
|
"appPlatform/overall"
|
|
"bytes"
|
|
"crypto/cipher"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/tjfoc/gmsm/sm4"
|
|
)
|
|
|
|
/*
|
|
*
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-08-28 14:51:02
|
|
@ 功能: SM4加密
|
|
@ 参数
|
|
|
|
#data 要加密的字符
|
|
#key 附加选项
|
|
|
|
@ 返回值
|
|
|
|
#
|
|
|
|
@ 方法原型
|
|
|
|
#
|
|
*/
|
|
func SM4Encrypt(data string, key ...string) (string, error) {
|
|
SM4Key := overall.CONSTANT_CONFIG.Appsetup.AppKey
|
|
if len(key) > 0 {
|
|
SM4Key = strings.Join(key, "-")
|
|
}
|
|
SM4Key = processString(SM4Key, 16, "s")
|
|
//字符串转byte切片
|
|
plainText := []byte(data)
|
|
|
|
SM4Iv := "04TzMuvkHm_EZnHm"
|
|
|
|
iv := []byte(SM4Iv)
|
|
keySm4 := []byte(SM4Key)
|
|
//实例化sm4加密对象
|
|
block, err := sm4.NewCipher(keySm4)
|
|
fmt.Printf("block:%v=====>%v\n", err, string(keySm4))
|
|
if err != nil {
|
|
return "1", err
|
|
}
|
|
//明文数据填充
|
|
paddingData := paddingLastGroup(plainText, block.BlockSize())
|
|
//声明SM4的加密工作模式
|
|
blockMode := cipher.NewCBCEncrypter(block, iv)
|
|
//为填充后的数据进行加密处理
|
|
cipherText := make([]byte, len(paddingData))
|
|
//使用CryptBlocks这个核心方法,将paddingData进行加密处理,将加密处理后的值赋值到cipherText中
|
|
blockMode.CryptBlocks(cipherText, paddingData)
|
|
//加密结果使用hex转成字符串,方便外部调用
|
|
cipherString := hex.EncodeToString(cipherText)
|
|
return cipherString, nil
|
|
}
|
|
|
|
// 明文数据填充
|
|
func paddingLastGroup(plainText []byte, blockSize int) []byte {
|
|
//1.计算最后一个分组中明文后需要填充的字节数
|
|
padNum := blockSize - len(plainText)%blockSize
|
|
//2.将字节数转换为byte类型
|
|
char := []byte{byte(padNum)}
|
|
//3.创建切片并初始化
|
|
newPlain := bytes.Repeat(char, padNum)
|
|
//4.将填充数据追加到原始数据后
|
|
newText := append(plainText, newPlain...)
|
|
return newText
|
|
}
|
|
|
|
// 去掉明文后面的填充数据
|
|
func unPaddingLastGroup(plainText []byte) []byte {
|
|
//1.拿到切片中的最后一个字节
|
|
length := len(plainText)
|
|
lastChar := plainText[length-1]
|
|
//2.将最后一个数据转换为整数
|
|
number := int(lastChar)
|
|
return plainText[:length-number]
|
|
}
|
|
|
|
/*
|
|
*
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-08-28 14:58:03
|
|
@ 功能: SM4解密
|
|
@ 参数
|
|
|
|
#
|
|
|
|
@ 返回值
|
|
|
|
#
|
|
|
|
@ 方法原型
|
|
|
|
#
|
|
*/
|
|
func SM4Decrypt(data string, key ...string) (string, error) {
|
|
SM4Key := overall.CONSTANT_CONFIG.Appsetup.AppKey
|
|
if len(key) > 0 {
|
|
SM4Key = strings.Join(key, "-")
|
|
}
|
|
SM4Key = processString(SM4Key, 16, "s")
|
|
SM4Iv := "04TzMuvkHm_EZnHm"
|
|
iv := []byte(SM4Iv)
|
|
keySm4 := []byte(SM4Key)
|
|
block, err := sm4.NewCipher(keySm4)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
//使用hex解码
|
|
decodeString, err := hex.DecodeString(data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
//CBC模式 优点:具有较好的安全性,能够隐藏明文的模式和重复性。 缺点:加密过程是串行的,不适合并行处理。
|
|
blockMode := cipher.NewCBCDecrypter(block, iv)
|
|
//下文有详解这段代码的含义
|
|
blockMode.CryptBlocks(decodeString, decodeString)
|
|
//去掉明文后面的填充数据
|
|
plainText := unPaddingLastGroup(decodeString)
|
|
|
|
return string(plainText), nil
|
|
}
|
|
|
|
// 判断字符串长度,多余的删除,不足的补充
|
|
func processString(s string, length int, pad string) string {
|
|
// 如果字符串长度已经符合要求,直接返回
|
|
if len(s) == length {
|
|
return s
|
|
}
|
|
|
|
// 如果字符串长度超过了要求,截取指定长度的部分
|
|
if len(s) > length {
|
|
return s[:length]
|
|
}
|
|
|
|
// 如果字符串长度不足,使用pad字符串进行补充
|
|
return s + padString(pad, length-len(s))
|
|
}
|
|
|
|
// 根据需要补充的字符和次数,生成补充字符串
|
|
func padString(pad string, times int) string {
|
|
var result string
|
|
for i := 0; i < times; i++ {
|
|
result += pad
|
|
}
|
|
return result
|
|
}
|
|
|