sdk_generate/internal/prompts/tools/crypt/aes.go

305 lines
8.0 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// aes.go
package crypt
import (
"context"
"fmt"
"github.com/sashabaranov/go-openai"
"github.com/sashabaranov/go-openai/jsonschema"
)
// ========== AES-CBC 加密工具 ==========
type AESCBCEncryptTool struct{}
func (t *AESCBCEncryptTool) Name() string { return "aes_cbc_encrypt" }
func (t *AESCBCEncryptTool) Description() string {
return "AES-CBC模式加密实现指南。当文档要求使用AES-CBC模式对请求体或敏感字段进行加密时使用包含PKCS7填充、IV生成和处理"
}
func (t *AESCBCEncryptTool) GetFunctionDefinition() openai.FunctionDefinition {
return openai.FunctionDefinition{
Name: t.Name(),
Description: t.Description(),
Parameters: jsonschema.Definition{
Type: jsonschema.Object,
Properties: map[string]jsonschema.Definition{
"key_length": {
Type: jsonschema.Integer,
Description: "密钥长度,可选 16(AES-128), 24(AES-192), 32(AES-256),默认 32",
Enum: []string{"16", "24", "32"},
},
"encoding": {
Type: jsonschema.String,
Description: "输出编码方式base64 或 hex默认 base64",
Enum: []string{"base64", "hex"},
},
},
Required: []string{},
},
}
}
func (t *AESCBCEncryptTool) GetDetail(ctx context.Context, params map[string]string) (string, error) {
keyLength := "32"
if v, ok := params["key_length"]; ok && v != "" {
keyLength = v
}
encoding := "base64"
if v, ok := params["encoding"]; ok && v != "" {
encoding = v
}
aesType := "256"
if keyLength == "16" {
aesType = "128"
} else if keyLength == "24" {
aesType = "192"
}
return fmt.Sprintf(`
### AES-CBC 加密完整实现指南
**适用场景**:文档要求使用 AES-CBC 模式进行对称加密
**配置参数**
- 密钥长度: %s 字节 (AES-%s)
- 编码方式: %s
**完整代码模板**
`+"```go"+`
package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"bytes"
)
// AESCBCEncrypt AES-CBC模式加密
func AESCBCEncrypt(plaintext []byte, key []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", fmt.Errorf("创建AES cipher失败: %%v", err)
}
padded := pkcs7Padding(plaintext, aes.BlockSize)
iv := make([]byte, aes.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
}
// AESCBCDecrypt AES-CBC模式解密
func AESCBCDecrypt(encryptedData string, key []byte) ([]byte, error) {
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)
}
if len(data) < aes.BlockSize {
return nil, fmt.Errorf("数据长度不足")
}
iv := data[:aes.BlockSize]
ciphertext := data[aes.BlockSize:]
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("创建AES cipher失败: %%v", err)
}
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 {
return nil, fmt.Errorf("填充数据无效")
}
return data[:length-padding], nil
}
`+"```"+`
**注意事项**
- 密钥长度必须是 16/24/32 字节
- IV 必须随机生成且每次不同
- IV 随密文一起传输
`, keyLength, aesType, encoding, encoding, encoding), nil
}
func (t *AESCBCEncryptTool) Execute(ctx context.Context, params map[string]string) (string, error) {
return t.GetDetail(ctx, params)
}
// ========== AES-ECB 加密工具 ==========
type AESECBEncryptTool struct{}
func (t *AESECBEncryptTool) Name() string { return "aes_ecb_encrypt" }
func (t *AESECBEncryptTool) Description() string {
return "AES-ECB模式加密实现指南。⚠注意ECB模式不安全仅用于兼容老旧系统"
}
func (t *AESECBEncryptTool) GetFunctionDefinition() openai.FunctionDefinition {
return openai.FunctionDefinition{
Name: t.Name(),
Description: t.Description(),
Parameters: jsonschema.Definition{
Type: jsonschema.Object,
Properties: map[string]jsonschema.Definition{
"key_length": {
Type: jsonschema.Integer,
Description: "密钥长度,可选 16(AES-128), 24(AES-192), 32(AES-256),默认 32",
Enum: []string{"16", "24", "32"},
},
"encoding": {
Type: jsonschema.String,
Description: "输出编码方式base64 或 hex默认 base64",
Enum: []string{"base64", "hex"},
},
},
Required: []string{},
},
}
}
func (t *AESECBEncryptTool) GetDetail(ctx context.Context, params map[string]string) (string, error) {
keyLength := "32"
if v, ok := params["key_length"]; ok && v != "" {
keyLength = v
}
encoding := "base64"
if v, ok := params["encoding"]; ok && v != "" {
encoding = v
}
return fmt.Sprintf(`
### AES-ECB 加密完整实现指南
**配置参数**
- 密钥长度: %s 字节
- 编码方式: %s
**完整代码模板**
`+"```go"+`
package crypto
import (
"crypto/aes"
"encoding/base64"
"encoding/hex"
"fmt"
"bytes"
)
// AESECBEncrypt AES-ECB模式加密
func AESECBEncrypt(plaintext []byte, key []byte, encoding string) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", fmt.Errorf("创建AES cipher失败: %%v", err)
}
padded := pkcs7Padding(plaintext, aes.BlockSize)
ciphertext := make([]byte, len(padded))
for i := 0; i < len(padded); i += aes.BlockSize {
block.Encrypt(ciphertext[i:i+aes.BlockSize], padded[i:i+aes.BlockSize])
}
if encoding == "hex" {
return hex.EncodeToString(ciphertext), nil
}
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// AESECBDecrypt AES-ECB模式解密
func AESECBDecrypt(encryptedData string, key []byte, encoding string) ([]byte, error) {
var ciphertext []byte
var err error
if encoding == "hex" {
ciphertext, err = hex.DecodeString(encryptedData)
} else {
ciphertext, err = base64.StdEncoding.DecodeString(encryptedData)
}
if err != nil {
return nil, fmt.Errorf("解码失败: %%v", err)
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("创建AES cipher失败: %%v", err)
}
if len(ciphertext)%%aes.BlockSize != 0 {
return nil, fmt.Errorf("密文长度不是块大小的整数倍")
}
plaintext := make([]byte, len(ciphertext))
for i := 0; i < len(ciphertext); i += aes.BlockSize {
block.Decrypt(plaintext[i:i+aes.BlockSize], ciphertext[i:i+aes.BlockSize])
}
plaintext, err = pkcs7UnPadding(plaintext)
if err != nil {
return nil, fmt.Errorf("去除填充失败: %%v", err)
}
return plaintext, nil
}
`+"```"+`
`, keyLength, encoding, keyLength), nil
}
func (t *AESECBEncryptTool) Execute(ctx context.Context, params map[string]string) (string, error) {
return t.GetDetail(ctx, params)
}