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

  1. Verify the exact bytes hashed by the signer match msgHash (same SHA-256 digest of the same payload)
  2. Ensure the identity certificate belongs to the node that produced the signature (check cert rotation / MSP updates)
  3. Confirm the signature is in ASN.1 DER form (ECDSA-Sig-Value); convert raw r||s signatures with ecdsa.ParseDSSSignature/re-encode
  4. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/7953317410a64713. Report an issue: GitHub.