package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
)
const (
KEY_ALGORITHM = "RSA"
SIGNATURE_ALGORITHM = "SHA1-RSA"
)
func loadPrivateKeyFromPemStr(privKeyStr string) (*rsa.PrivateKey, error) {
block, _ := pem.Decode([]byte(privKeyStr))
if block == nil {
return nil, errors.New("failed to parse PEM block containing the key")
}
privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return privKey, nil
}
func loadPublicKeyFromPemStr(pubKeyStr string) (*rsa.PublicKey, error) {
block, _ := pem.Decode([]byte(pubKeyStr))
if block == nil {
return nil, errors.New("failed to parse PEM block containing the key")
}
pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
rsaPub, ok := pubKey.(*rsa.PublicKey)
if !ok {
return nil, errors.New("not an RSA public key")
}
return rsaPub, nil
}
func Sign(data []byte, privateKeyStr string) (string, error) {
privateKey, err := loadPrivateKeyFromPemStr(privateKeyStr)
if err != nil {
return "", err
}
hasher := sha1.New()
hasher.Write(data)
digest := hasher.Sum(nil)
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, digest)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(signature), nil
}
func Verify(data []byte, publicKeyStr, signBase64 string) (bool, error) {
publicKey, err := loadPublicKeyFromPemStr(publicKeyStr)
if err != nil {
return false, err
}
signature, err := base64.StdEncoding.DecodeString(signBase64)
if err != nil {
return false, err
}
hasher := sha1.New()
hasher.Write(data)
digest := hasher.Sum(nil)
return rsa.VerifyPKCS1v15(publicKey, crypto.SHA1, digest, signature) == nil, nil
}
func main() {
privateKeyStr := `-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ7XW/9k3V0w/R6FefDktCEMpUoHTITgkpxi+av6atqj/Q/4dcUh5DhsmNcUhr8G3AmDz0IIXGkhPVNIrEazZvkcri02cemfpRhis4L+XB+YTsbnqo7LGkrxCxZIjyP9TkksUI9/Yi/cJbg4ZI/oEbUoCM66BaoUeLm9fXThUNebAgMBAAECgYBB7T7Y3MNoB4o3Xc0D59i/kuETvb3LtO4FDKt17uTkxIWnWEeBP5TaunAhbPqUVMOFC3k9ffzlAY/TfmlKmvGUsKBHTJA6YETvtp3bqGyeb4xU6J6/YDIy45ca3MJ+ZLkc7LFVp6ZRHWPKaxCoA2dCbMjOFHEv3EkF3Gq9fA+riQJBAObKROYkB5RWogPSHzWD/klZ/7Nxakld+/2dXMeDK355Ea9tAaYxev8u5NDiRGYo8e0PdPVSo4MAIVdCaK439ucCQQCwMSNmaoXCscgABHHaGil1Bw0CShod+oH2d/NZErecb7oyCZUV/2llTushwp8K6whKe1x8ZfZNBd5lt37q0OctAkB40s/7REWLjUdIhMq985o+wJUzVl70hfWUsruN38f3cF6n3oOMhD8GNYCpMqvoZ+sv1nW+sULVJE5QJn4zJy1lAkA7ycDofRc81RU4JEn6J8yPoL/iWgD40UwOte+G91oFJMi7OBM2LsC2FwylHSTZEJ50n93nfLYStv4b6COSTSdVAkEApgf/0at6okMkIpLgzXla9W+L4z8dX/L2AUIJ9NNyXHSvrMACnaj6O4QZ35kvm8Hm0usmbmaW9r3Pzd38x1F6LQ==
-----END RSA PRIVATE KEY-----`
publicKeyStr := `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCe11v/ZN1dMP0ehXnw5LQhDKVKB0yE4JKcYvmr+mrao/0P+HXFIeQ4bJjXFIa/BtwJg89CCFxpIT1TSKxGs2b5HK4tNnHpn6UYYrOC/lwfmE7G56qOyxpK8QsWSI8j/U5JLFCPf2Iv3CW4OGSP6BG1KAjOugWqFHi5vX104VDXmwIDAQAB
-----END PUBLIC KEY-----`
data := `{"bizData":"QBnAEOgqOGybyS+weMMQaVn8i0KQ+MrcTt/y2SquCrZBbMvMhygA269zURM56yLaD4H2b6xfZgCzJb58yNh6cylTFeELVR1g7B6ZWOCiH7Y=","channelId":"105900001","timestamp":1716124734964}`
signatureBase64, err := Sign([]byte(data), privateKeyStr)
if err != nil {
fmt.Println("Error signing:", err)
return
}
fmt.Println("Signature:", signatureBase64)
isValid, err := Verify([]byte(data), publicKeyStr, signatureBase64)
if err != nil {
fmt.Println("Error verifying:", err)
return
}
fmt.Println("Signature is valid:", isValid)
}