// sm4.go package crypt import ( "context" "fmt" "github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai/jsonschema" ) // ========== SM4-CBC 加密工具 ========== type SM4CBCEncryptTool struct{} func (t *SM4CBCEncryptTool) Name() string { return "sm4_cbc_encrypt" } func (t *SM4CBCEncryptTool) Description() string { return "SM4国密对称加密(CBC模式)实现指南。当文档要求使用国密SM4算法进行对称加密时使用。⚠️ 必须使用 github.com/tjfoc/gmsm 库,不要自己实现!" } func (t *SM4CBCEncryptTool) GetFunctionDefinition() openai.FunctionDefinition { return openai.FunctionDefinition{ Name: t.Name(), Description: t.Description(), Parameters: jsonschema.Definition{ Type: jsonschema.Object, Properties: map[string]jsonschema.Definition{ "encoding": { Type: jsonschema.String, Description: "输出编码方式,base64 或 hex,默认 base64", Enum: []string{"base64", "hex"}, }, }, Required: []string{}, }, } } func (t *SM4CBCEncryptTool) GetDetail(ctx context.Context, params map[string]string) (string, error) { encoding := "base64" if v, ok := params["encoding"]; ok && v != "" { encoding = v } return fmt.Sprintf(` ### SM4-CBC 国密对称加密完整实现指南 **⚠️ 重要:必须使用第三方库,不要自己实现 SM4 算法!** **推荐使用:github.com/tjfoc/gmsm** **前置要求**: `+"```bash"+` go get github.com/tjfoc/gmsm `+"```"+` **配置参数**: - 编码方式: %s **完整代码模板(请直接复制使用)**: `+"```go"+` package crypto import ( "crypto/cipher" "crypto/rand" "encoding/base64" "encoding/hex" "fmt" "io" "bytes" "github.com/tjfoc/gmsm/sm4" // ⚠️ 必须使用此库,不要自己实现SM4 ) // SM4CBCEncrypt SM4-CBC模式加密 // 使用 github.com/tjfoc/gmsm/sm4 实现 func SM4CBCEncrypt(plaintext []byte, key []byte) (string, error) { if len(key) != 16 { return "", fmt.Errorf("SM4密钥长度必须为16字节") } // 使用 gmsm 库创建 SM4 cipher block, err := sm4.NewCipher(key) if err != nil { return "", fmt.Errorf("创建SM4 cipher失败: %%v", err) } padded := pkcs7Padding(plaintext, block.BlockSize()) iv := make([]byte, block.BlockSize()) if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", fmt.Errorf("生成IV失败: %%v", err) } mode := cipher.NewCBCEncrypter(block, iv) ciphertext := make([]byte, len(padded)) mode.CryptBlocks(ciphertext, padded) result := append(iv, ciphertext...) if "%s" == "hex" { return hex.EncodeToString(result), nil } return base64.StdEncoding.EncodeToString(result), nil } // SM4CBCDecrypt SM4-CBC模式解密 // 使用 github.com/tjfoc/gmsm/sm4 实现 func SM4CBCDecrypt(encryptedData string, key []byte) ([]byte, error) { if len(key) != 16 { return nil, fmt.Errorf("SM4密钥长度必须为16字节") } var data []byte var err error if "%s" == "hex" { data, err = hex.DecodeString(encryptedData) } else { data, err = base64.StdEncoding.DecodeString(encryptedData) } if err != nil { return nil, fmt.Errorf("解码失败: %%v", err) } block, err := sm4.NewCipher(key) if err != nil { return nil, fmt.Errorf("创建SM4 cipher失败: %%v", err) } blockSize := block.BlockSize() if len(data) < blockSize { return nil, fmt.Errorf("数据长度不足") } iv := data[:blockSize] ciphertext := data[blockSize:] mode := cipher.NewCBCDecrypter(block, iv) plaintext := make([]byte, len(ciphertext)) mode.CryptBlocks(plaintext, ciphertext) plaintext, err = pkcs7UnPadding(plaintext) if err != nil { return nil, fmt.Errorf("去除填充失败: %%v", err) } return plaintext, nil } // pkcs7Padding PKCS7填充 func pkcs7Padding(data []byte, blockSize int) []byte { padding := blockSize - len(data)%%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(data, padText...) } // pkcs7UnPadding 去除PKCS7填充 func pkcs7UnPadding(data []byte) ([]byte, error) { length := len(data) if length == 0 { return nil, fmt.Errorf("数据为空") } padding := int(data[length-1]) if padding > length || padding == 0 { return nil, fmt.Errorf("无效的填充") } for i := length - padding; i < length; i++ { if data[i] != byte(padding) { return nil, fmt.Errorf("无效的填充") } } return data[:length-padding], nil } `+"```"+` **⚠️ 重要提醒**: 1. **不要自己实现 SM4 算法**,请直接使用 github.com/tjfoc/gmsm 2. 这个库是国密官方推荐的 Go 实现,安全可靠 3. 在 go.mod 中添加依赖:`+"`require github.com/tjfoc/gmsm v1.4.1`"+` **注意事项**: - SM4 密钥固定为 16 字节 - IV 必须随机生成且每次不同 - CBC 模式需要 IV,ECB 模式不需要 `, encoding, encoding, encoding), nil } func (t *SM4CBCEncryptTool) Execute(ctx context.Context, params map[string]string) (string, error) { return t.GetDetail(ctx, params) } // ========== SM4-ECB 加密工具 ========== type SM4ECBEncryptTool struct{} func (t *SM4ECBEncryptTool) Name() string { return "sm4_ecb_encrypt" } func (t *SM4ECBEncryptTool) Description() string { return "SM4国密对称加密(ECB模式)实现指南。⚠️ ECB模式不安全,仅用于兼容老旧系统。必须使用 github.com/tjfoc/gmsm 库,不要自己实现!" } func (t *SM4ECBEncryptTool) GetFunctionDefinition() openai.FunctionDefinition { return openai.FunctionDefinition{ Name: t.Name(), Description: t.Description(), Parameters: jsonschema.Definition{ Type: jsonschema.Object, Properties: map[string]jsonschema.Definition{ "encoding": { Type: jsonschema.String, Description: "输出编码方式,base64 或 hex,默认 base64", Enum: []string{"base64", "hex"}, }, }, Required: []string{}, }, } } func (t *SM4ECBEncryptTool) GetDetail(ctx context.Context, params map[string]string) (string, error) { encoding := "base64" if v, ok := params["encoding"]; ok && v != "" { encoding = v } return fmt.Sprintf(` ### SM4-ECB 国密对称加密完整实现指南 **⚠️ 重要提示**:ECB模式不安全,仅用于兼容老旧系统。 **⚠️ 重要:必须使用第三方库,不要自己实现 SM4 算法!** **推荐使用:github.com/tjfoc/gmsm** **前置要求**: `+"```bash"+` go get github.com/tjfoc/gmsm `+"```"+` **配置参数**: - 编码方式: %s **完整代码模板(请直接复制使用)**: `+"```go"+` package crypto import ( "encoding/base64" "encoding/hex" "fmt" "bytes" "github.com/tjfoc/gmsm/sm4" // ⚠️ 必须使用此库,不要自己实现SM4 ) // SM4ECBEncrypt SM4-ECB模式加密 // 使用 github.com/tjfoc/gmsm/sm4 实现 func SM4ECBEncrypt(plaintext []byte, key []byte) (string, error) { if len(key) != 16 { return "", fmt.Errorf("SM4密钥长度必须为16字节") } block, err := sm4.NewCipher(key) if err != nil { return "", fmt.Errorf("创建SM4 cipher失败: %%v", err) } padded := pkcs7Padding(plaintext, block.BlockSize()) ciphertext := make([]byte, len(padded)) for i := 0; i < len(padded); i += block.BlockSize() { block.Encrypt(ciphertext[i:i+block.BlockSize()], padded[i:i+block.BlockSize()]) } if "%s" == "hex" { return hex.EncodeToString(ciphertext), nil } return base64.StdEncoding.EncodeToString(ciphertext), nil } // SM4ECBDecrypt SM4-ECB模式解密 // 使用 github.com/tjfoc/gmsm/sm4 实现 func SM4ECBDecrypt(encryptedData string, key []byte) ([]byte, error) { if len(key) != 16 { return nil, fmt.Errorf("SM4密钥长度必须为16字节") } var ciphertext []byte var err error if "%s" == "hex" { ciphertext, err = hex.DecodeString(encryptedData) } else { ciphertext, err = base64.StdEncoding.DecodeString(encryptedData) } if err != nil { return nil, fmt.Errorf("解码失败: %%v", err) } block, err := sm4.NewCipher(key) if err != nil { return nil, fmt.Errorf("创建SM4 cipher失败: %%v", err) } blockSize := block.BlockSize() if len(ciphertext)%%blockSize != 0 { return nil, fmt.Errorf("密文长度不是块大小的整数倍") } plaintext := make([]byte, len(ciphertext)) for i := 0; i < len(ciphertext); i += blockSize { block.Decrypt(plaintext[i:i+blockSize], ciphertext[i:i+blockSize]) } plaintext, err = pkcs7UnPadding(plaintext) if err != nil { return nil, fmt.Errorf("去除填充失败: %%v", err) } return plaintext, nil } // pkcs7Padding 和 pkcs7UnPadding 函数请参考 CBC 模式实现 `+"```"+` **⚠️ 重要提醒**: 1. **不要自己实现 SM4 算法**,请直接使用 github.com/tjfoc/gmsm 2. 这个库是国密官方推荐的 Go 实现,安全可靠 3. 在 go.mod 中添加依赖:`+"`require github.com/tjfoc/gmsm v1.4.1`"+` **⚠️ 安全警告**: - ECB模式不应在新系统中使用 - 仅用于兼容老旧的国密系统 - 推荐使用 SM4-CBC 模式 `, encoding, encoding, encoding), nil } func (t *SM4ECBEncryptTool) Execute(ctx context.Context, params map[string]string) (string, error) { return t.GetDetail(ctx, params) }