{"record":{"id":"7953317410a64713","repo":"hyperledger/fabric","slug":"signature-invalid","errorCode":null,"errorMessage":"signature invalid","messagePattern":"signature invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/util.go","lineNumber":732,"sourceCode":"\tblock, _ := pem.Decode(identity)\n\tif block == nil {\n\t\treturn errors.New(\"pem decoding failed\")\n\t}\n\n\tcert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"key extraction failed\")\n\t}\n\n\tpubKey, isECDSA := cert.PublicKey.(*ecdsa.PublicKey)\n\tif !isECDSA {\n\t\treturn errors.New(\"not valid public key\")\n\t}\n\n\tvalidSignature := ecdsa.VerifyASN1(pubKey, msgHash, signature)\n\n\tif !validSignature {\n\t\treturn errors.New(\"signature invalid\")\n\t}\n\treturn nil\n}\n\nfunc SHA256Digest(data []byte) []byte {\n\thash := sha256.Sum256(data)\n\treturn hash[:]\n}\n\n// VerifyBlocksBFT verifies the given consecutive sequence of blocks is valid, always verifies signature,\n// and returns nil if it's valid, else an error.\nfunc VerifyBlocksBFT(blocks []*common.Block, signatureVerifier protoutil.BlockVerifierFunc, vb protoutil.VerifierBuilder) error {\n\treturn verifyBlockSequence(blocks, signatureVerifier, vb)\n}\n\nfunc verifyBlockSequence(blockBuff []*common.Block, signatureVerifier protoutil.BlockVerifierFunc, vb protoutil.VerifierBuilder) error {\n\tif len(blockBuff) == 0 {\n\t\treturn errors.New(\"buffer is empty\")","sourceCodeStart":714,"sourceCodeEnd":750,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/util.go#L714-L750","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nsig := rawSig // fixed-width r||s bytes\nerr := VerifySignature(certPEM, hash, sig) // VerifyASN1 fails\n// after\nr, s := decodeRawSig(rawSig)\nsig, _ := asn1.Marshal(ecdsaSignature{R: r, S: s})\nerr := VerifySignature(certPEM, hash, sig)","handlingStrategy":"validation","validationCode":"if len(signature) == 0 { return errors.New(\"empty signature\") }\nif len(msgHash) != sha256.Size { return fmt.Errorf(\"expected 32-byte hash, got %d\", len(msgHash)) }","typeGuard":"func isDERECDSASignature(sig []byte) bool {\n    var s struct{ R, S big.Int }\n    _, err := asn1.Unmarshal(sig, &s)\n    return err == nil\n}","tryCatchPattern":"err := cluster.VerifySignature(identityPEM, msgHash, signature)\nif err != nil && strings.Contains(err.Error(), \"signature invalid\") {\n    // signature/key mismatch: log both cert fingerprints and payload hash to diagnose\n    return fmt.Errorf(\"signature does not match identity: %w\", err)\n}","preventionTips":["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"],"tags":["signature","ecdsa","crypto"],"backgroundTag":"signature-verification-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}