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
- Validate all key components are non-nil and positive before signing/verifying.
- Regenerate parameters with GenerateParameters and keys with GenerateKey if the source is untrusted.
- Compare key parameters (P, Q, G) bit-lengths against FIPS 186-3 sizes.
- 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
- Always check dsa.ErrInvalidPublicKey when importing keys from external sources.
- Generate keys only via GenerateParameters + GenerateKey.
- Consider migrating DSA to ECDSA/Ed25519 to reduce legacy exposure.
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
- crypto/ecdh: private key and public key curves do not match
- crypto/ecdh: invalid private key
- crypto/ecdh: invalid public key
- crypto/dsa: use of DSA is not allowed in FIPS 140-only mode
- crypto/dsa: invalid ParameterSizes
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/a8d42e3b434b044b.
Report an issue: GitHub.