{"record":{"id":"9235beb96c779fa0","repo":"golang/go","slug":"tls-client-certificate-used-with-invalid-signatur","errorCode":null,"errorMessage":"tls: client certificate used with invalid signature algorithm","messagePattern":"tls: client certificate used with invalid signature algorithm","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_server.go","lineNumber":781,"sourceCode":"\t\t// certificateVerifyMsg is included in the transcript, but not until\n\t\t// after we verify the handshake signature, since the state before\n\t\t// this message was sent is used.\n\t\tmsg, err = c.readHandshake(nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcertVerify, ok := msg.(*certificateVerifyMsg)\n\t\tif !ok {\n\t\t\tc.sendAlert(alertUnexpectedMessage)\n\t\t\treturn unexpectedMessageError(certVerify, msg)\n\t\t}\n\n\t\tvar sigType uint8\n\t\tvar sigHash crypto.Hash\n\t\tif c.vers >= VersionTLS12 {\n\t\t\tif !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {\n\t\t\t\tc.sendAlert(alertIllegalParameter)\n\t\t\t\treturn errors.New(\"tls: client certificate used with invalid signature algorithm\")\n\t\t\t}\n\t\t\tsigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)\n\t\t\tif err != nil {\n\t\t\t\treturn c.sendAlert(alertInternalError)\n\t\t\t}\n\t\t\tif sigHash == crypto.SHA1 {\n\t\t\t\ttlssha1.Value() // ensure godebug is initialized\n\t\t\t\ttlssha1.IncNonDefault()\n\t\t\t}\n\t\t\tif hs.finishedHash.buffer == nil {\n\t\t\t\tc.sendAlert(alertInternalError)\n\t\t\t\treturn errors.New(\"tls: internal error: did not keep handshake transcript for TLS 1.2\")\n\t\t\t}\n\t\t\tif err := verifyHandshakeSignature(sigType, pub, sigHash, hs.finishedHash.buffer, certVerify.signature); err != nil {\n\t\t\t\tc.sendAlert(alertDecryptError)\n\t\t\t\treturn errors.New(\"tls: invalid signature by the client certificate: \" + err.Error())\n\t\t\t}\n\t\t} else {","sourceCodeStart":763,"sourceCodeEnd":799,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_server.go#L763-L799","documentation":"The client's CertificateVerify message used a signature algorithm that the server did not advertise in its CertificateRequest. TLS 1.2+ requires the client to pick from the server's supported_signature_algorithms list; picking outside it is illegal_parameter.","triggerScenarios":"In the TLS 1.2 client-cert path, isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) returned false. The client signed with e.g. RSA-PKCS1-SHA1 when the server only offered SHA256+.","commonSituations":"A client library defaulting to a weak or legacy signature algorithm (SHA1, MD5) against a hardened server, mismatched signature algorithm support between client and server policy, or a misconfigured client cert whose key only supports certain algorithms.","solutions":["Ensure the client signs CertificateVerify with one of the algorithms the server advertised in its CertificateRequest.","On the server side, broaden supported signature algorithms if interoperability with the client is required.","Update the client TLS stack — modern libraries pick from the server's list automatically.","Verify the client certificate's key type supports the algorithm being requested."],"exampleFix":"// Server: ensure the algorithm list matches what legitimate clients can use\ncfg := &tls.Config{\n    ClientAuth: tls.RequireAndVerifyClientCert,\n    // Go selects supported algorithms automatically; do not over-restrict.\n}\n\n// Client: use a current TLS library — Go picks from server's list.\n// Custom signing code must honor certReq.supportedSignatureAlgorithms.","handlingStrategy":"validation","validationCode":"// Client: pick a signature algorithm from the server's CertificateRequest\n// list. Go's standard machinery does this automatically.\n// For manual signers, intersect supported algorithms with the server list.","typeGuard":null,"tryCatchPattern":"// Server: broaden supported algorithms if interoperability is required,\n// or log which algorithm the client mis-used.\nif err != nil && strings.Contains(err.Error(), \"invalid signature algorithm\") {\n    log.Warn(\"client used unadvertised signature algorithm\",\n        \"remote\", conn.RemoteAddr())\n}","preventionTips":["Use a current TLS library for the client — it honors the server's algorithm list.","Do not hard-code SHA1 or other weak algorithms in custom signers.","Keep the server's algorithm list broad enough for legitimate clients."],"tags":["tls","server-handshake","client-certificate","signature-algorithm","tls12","protocol-violation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}