应用集成平台服务端
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.
 
 
 

154 lines
3.7 KiB

package publicmethod
import (
"appPlatform/overall"
"bytes"
"crypto/cipher"
"encoding/hex"
"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) ([]byte, 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 []byte(""), err
}
//使用hex解码
decodeString, err := hex.DecodeString(data)
if err != nil {
return []byte(""), err
}
//CBC模式 优点:具有较好的安全性,能够隐藏明文的模式和重复性。 缺点:加密过程是串行的,不适合并行处理。
blockMode := cipher.NewCBCDecrypter(block, iv)
//下文有详解这段代码的含义
blockMode.CryptBlocks(decodeString, decodeString)
//去掉明文后面的填充数据
plainText := unPaddingLastGroup(decodeString)
return 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
}