{"record":{"id":"a8d42e3b434b044b","repo":"golang/go","slug":"crypto-dsa-invalid-public-key","errorCode":null,"errorMessage":"crypto/dsa: invalid public key","messagePattern":"crypto/dsa: invalid public key","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/dsa/dsa.go","lineNumber":47,"sourceCode":"}\n\n// PublicKey represents a DSA public key.\ntype PublicKey struct {\n\tParameters\n\tY *big.Int\n}\n\n// PrivateKey represents a DSA private key.\ntype PrivateKey struct {\n\tPublicKey\n\tX *big.Int\n}\n\n// ErrInvalidPublicKey results when a public key is not usable by this code.\n// FIPS is quite strict about the format of DSA keys, but other code may be\n// less so. Thus, when using keys which may have been generated by other code,\n// this error must be handled.\nvar ErrInvalidPublicKey = errors.New(\"crypto/dsa: invalid public key\")\n\n// ParameterSizes is an enumeration of the acceptable bit lengths of the primes\n// in a set of DSA parameters. See FIPS 186-3, section 4.2.\ntype ParameterSizes int\n\nconst (\n\tL1024N160 ParameterSizes = iota\n\tL2048N224\n\tL2048N256\n\tL3072N256\n)\n\n// numMRTests is the number of Miller-Rabin primality tests that we perform. We\n// pick the largest recommended number from table C.1 of FIPS 186-3.\nconst numMRTests = 64\n\n// GenerateParameters puts a random, valid set of DSA parameters into params.\n// This function can take many seconds, even on fast machines.","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/dsa/dsa.go#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"Importing DSA keys from OpenSSL/other libraries; corrupted or truncated key bytes; keys whose parameters were never generated via GenerateParameters; partial key deserialization.","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)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate a DSA key before Sign/Verify:\nfunc dsaKeyOK(k *dsa.PublicKey) bool {\n    return k != nil && k.P != nil && k.Q != nil && k.G != nil && k.Y != nil &&\n        k.P.Sign() > 0 && k.Q.Sign() > 0 && k.G.Sign() > 0 && k.Y.Sign() > 0 &&\n        k.Q.BitLen()%8 == 0\n}","typeGuard":"func validDSAPublicKey(k *dsa.PublicKey) bool {\n    return k != nil && k.P != nil && k.Q != nil && k.G != nil && k.Y != nil &&\n        k.P.Sign() > 0 && k.Q.Sign() > 0 && k.G.Sign() > 0\n}","tryCatchPattern":"if err := dsa.Verify(&pub, hash, r, s); /* or Sign */ !ok /* or err */ {\n    if errors.Is(err, dsa.ErrInvalidPublicKey) {\n        // regenerate or reject the key\n    }\n}","preventionTips":["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."],"tags":["crypto","dsa","keys","validation","go","security"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}