我正在使用 Golang 验证由 ECDSA 密钥和 secp256r1/scep384r1/secp521r1 签署的数字签名。
secp256r1/scep384r1/secp521r1的签名验证性能差异令人震惊。
对于由密钥 secp256r1签名的数字签名,Golang 每秒能够验证大约 27k 个签名。
对于使用secp384r1 密钥签名的签名,每秒可以验证大约 1700 个签名,而对于使用 secp521r1 密钥签名的签名,每秒仅验证 350 个签名。
数字签名的验证差异确实很大,三种情况下的签名算法都是相同的,即SHA256和ECDSA。
用于验证签名的示例代码:
package main
import (
"crypto/ecdsa"
"crypto/sha256"
"encoding/asn1"
"encoding/base64"
"encoding/json"
"errors"
// "fmt"
"math/big"
"sync/atomic"
)
type ECDSASignature struct {
R, S *big.Int
}
type Envelope struct {
RawMessage json.RawMessage `json:"message"`
Message interface{} `json:"-"`
Signature string `json:"signature"`
}
func hash(b []byte) []byte {
h := sha256.New()
h.Write(b)
return h.Sum(nil)
}
func (e *Envelope) Validate(publicKey *ecdsa.PublicKey) bool{
der, err := base64.StdEncoding.DecodeString(e.Signature)
if err != nil {
return err
}
sig := &ECDSASignature{}
_, err = asn1.Unmarshal(der, sig)
if err != nil {
return err
}
h := hash(e.RawMessage)
valid := ecdsa.Verify(
publicKey,
h,
sig.R,
sig.S,
)
return valid
}
我在这里错过了什么吗?我是否需要以不同的方式处理 secp384r1 和 secp521r1 来验证签名?如何提高验证这些签名的性能?对于这些键类型,这是 Golang 中的预期行为吗?