golang/go · error

invalid ASN.1

Error message

invalid ASN.1

What it means

Thrown by parseSignature when the input byte slice is not a valid ASN.1 SEQUENCE containing exactly two INTEGERs (r, s) with no trailing data. This is the standard ECDSA signature format (DER-encoded ASN.1). Any structural violation — wrong tags, incorrect lengths, extra or missing fields — produces this error.

Source

Thrown at src/crypto/ecdsa/ecdsa.go:560

	k, err := publicKeyToFIPS(c, pub)
	if err != nil {
		return false
	}
	if err := ecdsa.Verify(c, k, hash, &ecdsa.Signature{R: r, S: s}); err != nil {
		return false
	}
	return true
}

func parseSignature(sig []byte) (r, s []byte, err error) {
	var inner cryptobyte.String
	input := cryptobyte.String(sig)
	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
		!input.Empty() ||
		!inner.ReadASN1Integer(&r) ||
		!inner.ReadASN1Integer(&s) ||
		!inner.Empty() {
		return nil, nil, errors.New("invalid ASN.1")
	}
	return r, s, nil
}

func publicKeyFromFIPS(curve elliptic.Curve, pub *ecdsa.PublicKey) (*PublicKey, error) {
	x, y, err := pointToAffine(curve, pub.Bytes())
	if err != nil {
		return nil, err
	}
	return &PublicKey{Curve: curve, X: x, Y: y}, nil
}

func privateKeyFromFIPS(curve elliptic.Curve, priv *ecdsa.PrivateKey) (*PrivateKey, error) {
	pub, err := publicKeyFromFIPS(curve, priv.PublicKey())
	if err != nil {
		return nil, err
	}
	return &PrivateKey{PublicKey: *pub, D: new(big.Int).SetBytes(priv.Bytes())}, nil

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure the signature is DER-encoded ASN.1 (produced by SignASN1 or compatible library) — if you have raw r,s values, use Sign/Verify with big.Int instead of ASN.1 variants.
  2. Verify the signature bytes are not corrupted: check length, first byte should be 0x30 (SEQUENCE tag).
  3. If interoperating with a system that uses IEEE P1363 format (fixed-width r||s), convert to DER before passing to ASN.1 functions.

Example fix

// before
// sigBytes is raw r||s concatenated (IEEE P1363 format)
ok := ecdsa.VerifyASN1(pub, hash, sigBytes)

// after
// convert P1363 to DER, or use VerifyASN1 with a properly DER-encoded signature
// generated by ecdsa.SignASN1
Defensive patterns

Strategy: validation

Validate before calling

func isValidASN1Signature(sig []byte) bool {
    s := cryptobyte.String(sig)
    var inner cryptobyte.String
    var r, ss big.Int
    return s.ReadASN1(&inner, asn1.SEQUENCE) && s.Empty() &&
        inner.ReadASN1Integer(&r) && inner.ReadASN1Integer(&ss) && inner.Empty()
}

Type guard

func isDERSignature(sig []byte) bool {
    return len(sig) > 0 && sig[0] == 0x30 // ASN.1 SEQUENCE tag
}

Try / catch

ok := ecdsa.VerifyASN1(pub, hash, sig)
if !ok {
    if !isDERSignature(sig) {
        // signature may be in IEEE P1363 (r||s) format — convert to DER
        return errors.New("signature not in DER format")
    }
    return errors.New("signature verification failed")
}

Prevention

When it happens

Trigger: Calling VerifyASN1 or any function that internally calls parseSignature with a malformed signature byte slice. Triggers include: passing raw r||s concatenated bytes instead of DER, truncated or corrupted DER, ASN.1 with negative integers (non-minimal encoding), or DER with extra trailing bytes after the SEQUENCE.

Common situations: Interoperability between systems that use different signature encodings (concatenated r,s vs DER); corrupted signature data from network transmission; signatures produced by non-standard libraries that don't follow strict DER; passing hex strings instead of decoded bytes.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/c8779a8040c0297b. Report an issue: GitHub.