119 lines
2.9 KiB
Go
119 lines
2.9 KiB
Go
// sm2.go
|
||
package crypt
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
|
||
"github.com/sashabaranov/go-openai"
|
||
"github.com/sashabaranov/go-openai/jsonschema"
|
||
)
|
||
|
||
type SM2SignTool struct{}
|
||
|
||
func (t *SM2SignTool) Name() string { return "sm2_sign" }
|
||
|
||
func (t *SM2SignTool) Description() string {
|
||
return "SM2国密签名实现指南。当文档要求使用国密SM2算法进行签名时使用,包含SM2公私钥加载和签名验证"
|
||
}
|
||
|
||
func (t *SM2SignTool) 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 *SM2SignTool) GetDetail(ctx context.Context, params map[string]string) (string, error) {
|
||
encoding := "base64"
|
||
if v, ok := params["encoding"]; ok && v != "" {
|
||
encoding = v
|
||
}
|
||
|
||
return fmt.Sprintf(`
|
||
### SM2国密签名完整实现指南
|
||
|
||
**前置要求**:需要安装 github.com/tjfoc/gmsm
|
||
|
||
`+"```bash"+`
|
||
go get github.com/tjfoc/gmsm
|
||
`+"```"+`
|
||
|
||
`+"```go"+`
|
||
package crypto
|
||
|
||
import (
|
||
"encoding/base64"
|
||
"encoding/hex"
|
||
"github.com/tjfoc/gmsm/sm2"
|
||
"github.com/tjfoc/gmsm/x509"
|
||
)
|
||
|
||
// SignWithSM2 使用SM2私钥签名
|
||
func SignWithSM2(data []byte, privateKeyPEM string) (string, error) {
|
||
// 加载SM2私钥
|
||
privateKey, err := x509.ReadPrivateKeyFromPem([]byte(privateKeyPEM), nil)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
// SM2签名
|
||
signature, err := sm2.Sign(privateKey, data)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return base64.StdEncoding.EncodeToString(signature), nil
|
||
}
|
||
|
||
// SignWithSM2AndEncoding 使用SM2私钥签名并指定编码方式
|
||
func SignWithSM2AndEncoding(data []byte, privateKeyPEM string, encoding string) (string, error) {
|
||
privateKey, err := x509.ReadPrivateKeyFromPem([]byte(privateKeyPEM), nil)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
signature, err := sm2.Sign(privateKey, data)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
if encoding == "hex" {
|
||
return hex.EncodeToString(signature), nil
|
||
}
|
||
return base64.StdEncoding.EncodeToString(signature), nil
|
||
}
|
||
|
||
// VerifySM2 验证SM2签名
|
||
func VerifySM2(data []byte, signature []byte, publicKeyPEM string) error {
|
||
publicKey, err := x509.ReadPublicKeyFromPem([]byte(publicKeyPEM))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return sm2.Verify(publicKey, data, signature)
|
||
}
|
||
`+"```"+`
|
||
|
||
**注意事项**:
|
||
- 确保私钥格式正确(PEM格式)
|
||
- SM2签名结果包含R和S两个大整数
|
||
- 确认编码方式(Base64还是Hex)
|
||
`, encoding), nil
|
||
}
|
||
|
||
func (t *SM2SignTool) Execute(ctx context.Context, params map[string]string) (string, error) {
|
||
return t.GetDetail(ctx, params)
|
||
}
|