在Golang中,我们可以使用第三方库来进行HS、RS、ES和ED签名与验证。
- HS(HMAC-SHA)签名与验证
对于HS签名算法,我们可以使用crypto/hmac包生成HMAC,并结合hash函数生成消息认证码。下面是示例代码:
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
)
func signHS(message string, key string) (string, error) {
keyBytes, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return "", err
}
hmac := hmac.New(sha256.New, keyBytes)
hmac.Write([]byte(message))
signature := hmac.Sum(nil)
return base64.StdEncoding.EncodeToString(signature), nil
}
func verifyHS(message string, signature string, key string) bool {
calculatedSignature, _ := signHS(message, key)
return calculatedSignature == signature
}
func main() {
message := "Hello World!"
key := "MzQ0Njg5MjA2NDExMTIyNDMyMDAwMDAxODc3NTM4NzE="
signature, err := signHS(message, key)
if err != nil {
panic(err)
}
fmt.Println("Signature:", signature)
valid := verifyHS(message, signature, key)
fmt.Println("Valid:", valid)
}
在上面的代码中,我们使用crypto/hmac包生成了一个HMAC-SHA256签名,并将其编码为base64格式字符串返回。然后,我们可以使用verifyHS函数来验证签名是否有效。
- RS(RSA)签名与验证
对于RS签名算法,我们可以使用crypto/rsa包生成数字签名,并使用公钥验证签名。下面是示例代码:
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"fmt"
)
func signRS(message string, privateKeyStr string) (string, error) {
block, _ := pem.Decode([]byte(privateKeyStr))
if block == nil || block.Type != "RSA PRIVATE KEY" {
return "", fmt.Errorf("invalid private key")
}
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return "", err
}
hashed := sha256.Sum256([]byte(message))
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(signature), nil
}
func verifyRS(message string, signature string, publicKeyStr string) bool {
publicBlock, _ := pem.Decode([]byte(publicKeyStr))
if publicBlock == nil || publicBlock.Type != "PUBLIC KEY" {
return false
}
pubInterface,err:=x509.ParsePKIXPublicKey(publicBlock.Bytes)
if err!=nil{
return false
}
publicKey,_:=pubInterface.(*rsa.PublicKey)
hashed := sha256.Sum256([]byte(message))
sigBytes,err:=base64.StdEncoding.DecodeString(signature)
if err!=nil{
return false
}
err = rsa.VerifyPKCS1v15(publicKey,crypto.SHA256,&hashed,sigBytes)
return err==nil
}
func main() {
message := "Hello World!"
privateKeyStr := `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAo5txO3i+g82v3gZ/RfLZD0b+xT3jF4aikmz8/vs5CnqIL0w
JrCz1O2XUAsyLDhX9P+MjjipWVdo8f1C6lGWso80dJovGffocO6Gcgb8Dnj7inRb
MmEQdygzBxLO4tI37Ld2/z7xuIHxDaWXEe9cTPYgsN6rHFDw97eoqecErHkUbbSy
gcmymBCK/7kpmsdnlqwSwKCGCyN8VOoP+z3kWYYuNbOVfJ62o4EzBYWe+QCChkwf
CDMYaoZpzmOWTLsEdjbCCZIDznG+cVH0WrCX+tz1ArXheSZ75vlKLTYIFjpHNIZ+
HEQs33DJbcDG60vFYZzpS/lvHi6bovVQlNsLxwIDAQABAoIBAGlzAcKP5C+bFaRO
PNayViL9FR/Mav8IeJjnxkfnCuOnVSC7SQOmCSAXA55/CtaRPmPUyxnKTNSkFo86
rMM9fiIeqgep/Xch17OHLSbBDHYHoEWULduEq41+YtufRT69Bvk99Dt/35dc2jTD
GNh5ZZTZx3jHa3vsOsSBwywuMnn2eMWb56ugojhhONlf0s7TnV+6J1pHs4yUZaTh
BvXamO5zWu9S/2DfLPDeij3rkKgGw3LrjNl64+vIDtqFkj+fQ+elCBLc6lcKo8N+
vvgPfT/tLbQ2d3slHxwyWSEdjJwbNy8vnbrASi4A0/GvIilhjEeEYOL72GGgzCXk
tDCjGAECgYEA2zwRGlpPkM+xpbmUM7nRAGBDWfc34lTkm+OfWr5JjsrUycse/MrH
KHigpjnKwSmsKBNQTjBCltb4pgAYf0fnqLYOyXxLFzPW+tOpFdIMHIkArQGmlqoE
peSzW80akprulkbRVhwx7sweTDZC27/K/UioX3dL7uv55bg05MyLIbMCgYEAuDPZ
bdHoYM+aJqx8KWPyZckynV93TOOSAH4sy9j+lCA7goHNJ/Nsi+hAgdeULa+kg/W/
eJMrCeF2RpMArOksqu1IdBpxUKziF5BHa/NEezAjPNwrPiAzcoYnuFeasw6tRyvm
Qt87l+17ILyA+n0glOdfkCdgrzyylUNIImINvtECgYBGz/5VdloWSxWE/BnAVXap
adDsgGHIP54niEEIHmUPebLQjtzjC8VY+W6tIrrL/pvKqJfOu1ZzWdpsnlvcFze5
akgD0e/3WJbly4kN+9aXy6BpkkNyqpZihehRUPr0ZZn7vnt8wQv52AFDcXs47wIM
Tm3KMWhmrHia/s56z3IeMQKBgQCXB1/wARdfGtU2+4dtKhLcBID/fhEcx/45Ed61
1lKHzwoOXOJidY3h06aR/vaT6Mlb5tp5+PqhSbToSNu0AKxtPqgmQ6yNWsbGoEGG
XbCbdCfG+Nds9VCupMM/eCICBfuHT8CiBuIx1eiuhUBjXOLML2wdjr/GHFNdhYBY
Nox05QKBgQCx/uBWTPcjpiTp+/DuOGeynaA9ytRkyoHblMudkA4v6+vGAivKyoYY
oeqvnpUprifnrGRwth7Id22jzjh7llBKRMPLmvAvbuKFu+fGpSse7EAs9Szww38t
N+tqZoWdug/jHIv94TksDEIkPgld2cdiRN16/RnwNxREAmIsbmRxNg==
-----END RSA PRIVATE KEY-----`
publicKeyStr := `-----BEGIN PUBLIC KEY-----
MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQEAo5txO3i+g82v3gZ/RfLZ
D0b+xT3jF4aikmz8/vs5CnqIL0wJrCz1O2XUAsyLDhX9P+MjjipWVdo8f1C6lGWs
o80dJovGffocO6Gcgb8Dnj7inRbMmEQdygzBxLO4tI37Ld2/z7xuIHxDaWXEe9cT
PYgsN6rHFDw97eoqecErHkUbbSygcmymBCK/7kpmsdnlqwSwKCGCyN8VOoP+z3kW
YYuNbOVfJ62o4EzBYWe+QCChkwfCDMYaoZpzmOWTLsEdjbCCZIDznG+cVH0WrCX+
tz1ArXheSZ75vlKLTYIFjpHNIZ+HEQs33DJbcDG60vFYZzpS/lvHi6bovVQlNsLx
wIDAQAB
-----END PUBLIC KEY-----`
signature, err := signRS(message, privateKeyStr)
if err != nil {
panic(err)
}
fmt.Println("Signature:", signature)
valid := verifyRS(message, signature, publicKeyStr)
fmt.Println("Valid:", valid)
}
在上面的代码中,我们使用crypto/rsa包生成了一个数字签名,并使用公钥验证签名是否有效。
- ES(ECDSA)签名与验证
对于ES签名算法,我们可以使用crypto/ecdsa包生成数字签名,并使用公钥验证签名。下面是示例代码:
”` package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/base64"
"encoding/pem"
"fmt"
)
func signES(message string, privateKeyStr string) (string, error) {
block, _ := pem.Decode([]byte(privateKeyStr))
if block == nil || block.Type != "EC PRIVATE KEY" {
return "", fmt.Errorf("invalid private key")
}
privateKey,err:=x509.ParseECPrivateKey(block.Bytes)
if err!=nil{
return "",err
}
hashed := sha256.Sum256([]byte(message))
r,s,err:=ecdsa.Sign(rand.Reader,privateKey,hashed[:])
if err!=nil{
return "",err
}
signature:=append(r.Bytes(),s.Bytes()...)
return base64.StdEncoding.EncodeToString(signature), nil
}
func verifyES(message string, signature string, publicKeyStr string) bool {
publicBlock,_:=pem.Decode([]byte(publicKeyStr))
if publicBlock==nil||publicBlock.Type!="EC PUBLIC KEY"{
return false
}
publicInterface,err:=x509.ParsePKIXPublicKey(publicBlock.Bytes)
if err!=nil{
return false
}
publicKey,_:=publicInterface.(*ecdsa.PublicKey)
sigBytes,err:=base64.StdEncoding.DecodeString(signature)
if err!=nil{
return false
}
rBytes:=sigBytes[0:32]
sBytes:=sigBytes[32:]
var r,s big.Int
r.SetBytes(rBytes)
s.SetBytes(sBytes)
hashed := sha256.Sum256([]byte(message))
return ecdsa.Verify(publicKey,&hashed,&r,&s)
}
func main() {
message := "Hello World!"
privateKeyStr := `-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJ5Mn8mW7z00bFRUqC2Sd8qwu9w0Y1xLJXyT6fIu1LmnoAoGCCqGSM49 AwEHoUQDQgAEZs+KRpHQzMT3kHYZOJ4+5AkGrPjP79xjBgzVnln0F12EeNvI76sA kP/NUo0mZiVL5wFcaS5HAt9tI6+aqk8f+w== —–END EC PRIVATE KEY—–`
publicKeyStr := `-----BEGIN EC PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZs+KRpHQzMT3kHYZOJ4+5AkGrPj7 9xjBgzVnln0F12EeNvI76sAkP/NUo0mZiVL5wFcaS5H