hyperledger/fabric · error
failed unmarshaling ECDSA signature on identity: %s
Error message
failed unmarshaling ECDSA signature on identity: %s
What it means
SanitizeX509Cert extracts the certificate's ECDSA signature and unmarshals the r,s integers. If cert.Signature is not a valid ASN.1 ECDSA signature pair, this wrapped error is returned. The sanitizer normalizes high-S signatures, so it must be able to parse the signature first.
Source
Thrown at common/crypto/sanitize.go:54
sID.IdBytes = finalPEM
return proto.Marshal(sID)
}
// SanitizeX509Cert sanitizes an X.509 certificate to ensure that the ECDSA signature uses a "low-S" value.
func SanitizeX509Cert(initialPEM []byte) ([]byte, error) {
der, _ := pem.Decode(initialPEM)
if der == nil {
return nil, errors.Errorf("failed to PEM decode identity bytes: %s", string(initialPEM))
}
cert, err := x509.ParseCertificate(der.Bytes)
if err != nil {
return nil, errors.Wrapf(err, "failed parsing certificate %s", string(initialPEM))
}
r, s, err := utils.UnmarshalECDSASignature(cert.Signature)
if err != nil {
return nil, errors.Wrapf(err, "failed unmarshaling ECDSA signature on identity: %s", string(initialPEM))
}
// We assume that the consenter and the CA use the same signature scheme.
curveOrderUsedByCryptoGen := cert.PublicKey.(*ecdsa.PublicKey).Curve.Params().N
halfOrder := new(big.Int).Rsh(curveOrderUsedByCryptoGen, 1)
// Low S, nothing to do here!
if s.Cmp(halfOrder) != 1 {
return initialPEM, nil
}
// Else it's high-S, so shift it below half the order.
s.Sub(curveOrderUsedByCryptoGen, s)
var newCert certificate
_, err = asn1.Unmarshal(cert.Raw, &newCert)
if err != nil {
return nil, errors.Wrapf(err, "failed unmarshaling certificate")
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure all node/CA certificates are ECDSA-signed (fabric's sanitizer assumes ECDSA keys — see the type assertion to *ecdsa.PublicKey)
- Re-issue certificates from a standards-compliant CA with proper DER ECDSA signatures
- Check the wrapped inner error to confirm whether the signature is malformed or of the wrong algorithm
- Verify the certificate wasn't truncated/re-encoded by intermediate tooling
Defensive patterns
Strategy: validation
Validate before calling
blk, _ := pem.Decode(certPEM)
cert, err := x509.ParseCertificate(blk.Bytes)
if err == nil {
if _, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok {
return errors.New("certificate must be ECDSA-signed for fabric sanitization")
}
} Try / catch
out, err := crypto.SanitizeX509Cert(certPEM)
if err != nil && strings.Contains(err.Error(), "failed unmarshaling ECDSA signature") {
// likely non-ECDSA cert; re-issue from CA with ECDSA
} Prevention
- Issue all fabric node/identity certs with ECDSA keys and signatures
- Reject non-ECDSA certs at enrollment time
- Use CAs that produce standards-compliant DER signatures
When it happens
Trigger: Sanitizing a certificate whose signature is not ECDSA (e.g. RSA or Ed25519 certs), or whose signature bytes are corrupted/non-standard ASN.1.
Common situations: Fabric deployment using RSA certificates where the sanitizer assumes ECDSA; certificates issued by a non-conformant CA encoding signatures differently; corrupted cert payloads in gossip or identity messages.
Related errors
- identity %s for MSP %s has a non canonical signature
- not valid public key
- policy for %s not satisfied
- error validating DeltaSet
- public keys do not match
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/9b69019ddaabbd8d.
Report an issue: GitHub.