package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"errors"
"fmt"
"strings"
)
// Rsa2SignatureService 提供RSA2签名和验证功能
type Rsa2SignatureService struct{}
// Verify 验证签名是否正确
func (s *Rsa2SignatureService) Verify(content, charset, publicKey, sign string) (bool, error) {
pubKey, err := ParsePublicKey(publicKey)
if err != nil {
return false, fmt.Errorf("解析公钥失败: %v", err)
}
contentBytes, err := getContentBytes(content, charset)
if err != nil {
return false, fmt.Errorf("内容编码失败: %v", err)
}
signBytes, err := base64.StdEncoding.DecodeString(sign)
if err != nil {
return false, fmt.Errorf("签名解码失败: %v", err)
}
hashed := sha256.Sum256(contentBytes)
err = rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, hashed[:], signBytes)
if err != nil {
if errors.Is(err, rsa.ErrVerification) {
return false, nil
}
return false, fmt.Errorf("验证签名时发生错误: %v", err)
}
return true, nil
}
// Sign 生成数字签名
func (s *Rsa2SignatureService) Sign(content, charset, privateKey string) (string, error) {
privKey, err := ParsePrivateKey(privateKey)
if err != nil {
return "", fmt.Errorf("解析私钥失败: %v", err)
}
contentBytes, err := getContentBytes(content, charset)
if err != nil {
return "", fmt.Errorf("内容编码失败: %v", err)
}
hashed := sha256.Sum256(contentBytes)
signature, err := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, hashed[:])
if err != nil {
return "", fmt.Errorf("签名生成失败: %v", err)
}
return base64.StdEncoding.EncodeToString(signature), nil
}
// GenerateKey 生成RSA密钥对
func (s *Rsa2SignatureService) GenerateKey() (publicKey, privateKey string, err error) {
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return "", "", fmt.Errorf("密钥生成失败: %v", err)
}
// 编码公钥
pubKeyBytes, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey)
if err != nil {
return "", "", fmt.Errorf("公钥编码失败: %v", err)
}
publicKey = base64.StdEncoding.EncodeToString(pubKeyBytes)
// 编码私钥
privKeyBytes, err := x509.MarshalPKCS8PrivateKey(privKey)
if err != nil {
return "", "", fmt.Errorf("私钥编码失败: %v", err)
}
privateKey = base64.StdEncoding.EncodeToString(privKeyBytes)
return publicKey, privateKey, nil
}
func GenerateKey() (string, string, error) {
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return "", "", err
}
pub := &priv.PublicKey
// 转换为 PKCS#8 私钥格式
privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
return "", "", err
}
// 转换为 X.509 公钥格式
pubBytes, err := x509.MarshalPKIXPublicKey(pub)
if err != nil {
return "", "", err
}
privBase64 := base64.StdEncoding.EncodeToString(privBytes)
pubBase64 := base64.StdEncoding.EncodeToString(pubBytes)
return pubBase64, privBase64, nil
}
// ParsePublicKey 解析Base64编码的公钥
func ParsePublicKey(publicKey string) (*rsa.PublicKey, error) {
derBytes, err := base64.StdEncoding.DecodeString(publicKey)
if err != nil {
return nil, err
}
pubKey, err := x509.ParsePKIXPublicKey(derBytes)
if err != nil {
return nil, err
}
rsaPubKey, ok := pubKey.(*rsa.PublicKey)
if !ok {
return nil, errors.New("非RSA公钥格式")
}
return rsaPubKey, nil
}
// ParsePrivateKey 解析Base64编码的私钥
func ParsePrivateKey(privateKey string) (*rsa.PrivateKey, error) {
derBytes, err := base64.StdEncoding.DecodeString(privateKey)
if err != nil {
return nil, err
}
privKey, err := x509.ParsePKCS8PrivateKey(derBytes)
if err != nil {
return nil, err
}
rsaPrivKey, ok := privKey.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("非RSA私钥格式")
}
return rsaPrivKey, nil
}
// getContentBytes 根据字符集编码内容
func getContentBytes(content, charset string) ([]byte, error) {
if charset == "" {
charset = "UTF-8"
}
switch strings.ToUpper(charset) {
case "UTF-8":
return []byte(content), nil
default:
return nil, fmt.Errorf("不支持的字符集: %s", charset)
}
}