hyperledger/fabric · error
signature invalid
Error message
signature invalid
What it means
This is the final verification failure in VerifySignature: the ECDSA key parsed fine, but ecdsa.VerifyASN1 returned false, meaning the signature does not match the given hash under the identity's public key. It indicates the signature was produced by a different key, over different bytes, or is malformed.
Source
Thrown at orderer/common/cluster/util.go:732
block, _ := pem.Decode(identity)
if block == nil {
return errors.New("pem decoding failed")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return errors.Wrap(err, "key extraction failed")
}
pubKey, isECDSA := cert.PublicKey.(*ecdsa.PublicKey)
if !isECDSA {
return errors.New("not valid public key")
}
validSignature := ecdsa.VerifyASN1(pubKey, msgHash, signature)
if !validSignature {
return errors.New("signature invalid")
}
return nil
}
func SHA256Digest(data []byte) []byte {
hash := sha256.Sum256(data)
return hash[:]
}
// VerifyBlocksBFT verifies the given consecutive sequence of blocks is valid, always verifies signature,
// and returns nil if it's valid, else an error.
func VerifyBlocksBFT(blocks []*common.Block, signatureVerifier protoutil.BlockVerifierFunc, vb protoutil.VerifierBuilder) error {
return verifyBlockSequence(blocks, signatureVerifier, vb)
}
func verifyBlockSequence(blockBuff []*common.Block, signatureVerifier protoutil.BlockVerifierFunc, vb protoutil.VerifierBuilder) error {
if len(blockBuff) == 0 {
return errors.New("buffer is empty")View on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the exact bytes hashed by the signer match msgHash (same SHA-256 digest of the same payload)
- Ensure the identity certificate belongs to the node that produced the signature (check cert rotation / MSP updates)
- Confirm the signature is in ASN.1 DER form (ECDSA-Sig-Value); convert raw r||s signatures with ecdsa.ParseDSSSignature/re-encode
- Compare certificate fingerprints on both sides to detect stale or mismatched identities
Example fix
// before
sig := rawSig // fixed-width r||s bytes
err := VerifySignature(certPEM, hash, sig) // VerifyASN1 fails
// after
r, s := decodeRawSig(rawSig)
sig, _ := asn1.Marshal(ecdsaSignature{R: r, S: s})
err := VerifySignature(certPEM, hash, sig) Defensive patterns
Strategy: validation
Validate before calling
if len(signature) == 0 { return errors.New("empty signature") }
if len(msgHash) != sha256.Size { return fmt.Errorf("expected 32-byte hash, got %d", len(msgHash)) } Type guard
func isDERECDSASignature(sig []byte) bool {
var s struct{ R, S big.Int }
_, err := asn1.Unmarshal(sig, &s)
return err == nil
} Try / catch
err := cluster.VerifySignature(identityPEM, msgHash, signature)
if err != nil && strings.Contains(err.Error(), "signature invalid") {
// signature/key mismatch: log both cert fingerprints and payload hash to diagnose
return fmt.Errorf("signature does not match identity: %w", err)
} Prevention
- Hash the exact same payload bytes on both sides (single SHA-256)
- Use ASN.1 DER signatures (ECDSA-Sig-Value) with VerifyASN1
- After cert rotation, refresh identities on all nodes before exchanging signed messages
- Compare cert fingerprints between peers when debugging
When it happens
Trigger: The signature was computed over a different payload than msgHash passed in; the signer identity and verification certificate belong to different nodes; a non-ASN1 (raw r||s) signature format is passed to VerifyASN1; payload was mutated in transit.
Common situations: Two orderer nodes exchanging TLS-bound messages after cert rotation where a stale cert is used for verification; mismatched hashing of the binding payload (hashing twice or not at all); signatures copied from DER-encoded ECDSA-Sig-Value vs fixed-width formats.
Related errors
- not valid public key
- found unknown private key type (%T) in msg signing
- failed unmarshaling ECDSA signature on identity: %s
- failed marshaling ECDSA signature
- identity %s for MSP %s has a non canonical signature
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/7953317410a64713.
Report an issue: GitHub.