golang/go · error

crypto/dsa: invalid public key

Error message

crypto/dsa: invalid public key

What it means

ErrInvalidPublicKey is a package-level sentinel indicating a DSA public key is malformed or fails validation. The doc comment notes FIPS is strict about DSA key format; other code may be more permissive, so keys imported from external sources must be checked. It is returned by Sign/Verify when key parameters (P, Q, G, X/Y) are non-positive, the subgroup order bit-length is not a multiple of 8, or the key otherwise fails the algorithm's preconditions.

Source

Thrown at src/crypto/dsa/dsa.go:47

}

// PublicKey represents a DSA public key.
type PublicKey struct {
	Parameters
	Y *big.Int
}

// PrivateKey represents a DSA private key.
type PrivateKey struct {
	PublicKey
	X *big.Int
}

// ErrInvalidPublicKey results when a public key is not usable by this code.
// FIPS is quite strict about the format of DSA keys, but other code may be
// less so. Thus, when using keys which may have been generated by other code,
// this error must be handled.
var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key")

// ParameterSizes is an enumeration of the acceptable bit lengths of the primes
// in a set of DSA parameters. See FIPS 186-3, section 4.2.
type ParameterSizes int

const (
	L1024N160 ParameterSizes = iota
	L2048N224
	L2048N256
	L3072N256
)

// numMRTests is the number of Miller-Rabin primality tests that we perform. We
// pick the largest recommended number from table C.1 of FIPS 186-3.
const numMRTests = 64

// GenerateParameters puts a random, valid set of DSA parameters into params.
// This function can take many seconds, even on fast machines.

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Validate all key components are non-nil and positive before signing/verifying.
  2. Regenerate parameters with GenerateParameters and keys with GenerateKey if the source is untrusted.
  3. Compare key parameters (P, Q, G) bit-lengths against FIPS 186-3 sizes.
  4. Consider migrating off DSA entirely (DSA is legacy; prefer ECDSA/Ed25519).
Defensive patterns

Strategy: validation

Validate before calling

// Validate a DSA key before Sign/Verify:
func dsaKeyOK(k *dsa.PublicKey) bool {
    return k != nil && k.P != nil && k.Q != nil && k.G != nil && k.Y != nil &&
        k.P.Sign() > 0 && k.Q.Sign() > 0 && k.G.Sign() > 0 && k.Y.Sign() > 0 &&
        k.Q.BitLen()%8 == 0
}

Type guard

func validDSAPublicKey(k *dsa.PublicKey) bool {
    return k != nil && k.P != nil && k.Q != nil && k.G != nil && k.Y != nil &&
        k.P.Sign() > 0 && k.Q.Sign() > 0 && k.G.Sign() > 0
}

Try / catch

if err := dsa.Verify(&pub, hash, r, s); /* or Sign */ !ok /* or err */ {
    if errors.Is(err, dsa.ErrInvalidPublicKey) {
        // regenerate or reject the key
    }
}

Prevention

When it happens

Trigger: Calling dsa.Sign or dsa.Verify with a PrivateKey/PublicKey whose P, Q, G, or X has Sign() <= 0, or where priv.Q.BitLen() % 8 != 0; loading a key produced by non-Go tooling that does not meet FIPS key constraints.

Common situations: Importing DSA keys from OpenSSL/other libraries; corrupted or truncated key bytes; keys whose parameters were never generated via GenerateParameters; partial key deserialization.

Related errors


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