package publicmethod import ( "appPlatform/overall" "crypto/cipher" "encoding/hex" "strings" "github.com/tjfoc/gmsm/sm4" ) // 判断字符串长度,多余的删除,不足的补充 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 getSm4IvRandString(length int) (sm4Iv string) { for { sm4IvStr, err := GenerateRandomString(length) if err == nil { sm4Iv = sm4IvStr break } } return } /* * @ 作者: 秦东 @ 时间: 2026-01-20 14:38:09 @ 功能: SM4加密方法 @ 参数 #data 要加密的字符 #key 附加选项 @ 返回值 #加密后的字符 #error */ func SM4EncryptNew(data string, class int, key ...string) (string, string, error) { SM4Key := overall.CONSTANT_CONFIG.Appsetup.Sm4Key if len(key) > 0 { SM4Key = strings.Join(key, "-") } SM4Key = ProcessString(SM4Key, 16, "s") //字符串转byte切片 plainText := []byte(data) SM4Iv := getSm4IvRandString(16) if class == 1 { SM4Iv = overall.CONSTANT_CONFIG.Appsetup.Sm4Token } sm4Iv16 := ProcessString(SM4Iv, 16, "s") iv := []byte(sm4Iv16) keySm4 := []byte(SM4Key) //实例化sm4加密对象 block, err := sm4.NewCipher(keySm4) if err != nil { return "1", SM4Iv, 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, SM4Iv, nil } /* * @ 作者: 秦东 @ 时间: 2026-01-20 14:44:50 @ 功能: SM4解密新版 */ func SM4DecryptNew(data, sm4IvStr string, key ...string) ([]byte, error) { SM4Key := overall.CONSTANT_CONFIG.Appsetup.Sm4Key if len(key) > 0 { SM4Key = strings.Join(key, "-") } if len(key) > 0 { SM4Key = strings.Join(key, "-") } SM4Key = ProcessString(SM4Key, 16, "s") //sm4随机安全码 SM4Iv := overall.CONSTANT_CONFIG.Appsetup.Sm4Token if sm4IvStr != "" { SM4Iv = sm4IvStr } sm4Iv16 := ProcessString(SM4Iv, 16, "s") iv := []byte(sm4Iv16) 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 }