How to Fix SSL Handshake Failure When Using Client Certificates with wget


2 views

The SSL handshake failure error (specifically ssl3_alert_handshake_failure) typically occurs when wget fails to properly present your client certificate during TLS negotiation. While the certificate works in browsers, command-line tools like wget often require additional configuration.

Here's the proper syntax for client certificate authentication:

wget \
  --certificate=/path/to/client_cert.pem \
  --private-key=/path/to/client_key.pem \
  --ca-certificate=/path/to/ca_bundle.pem \
  https://secure.example.com/resource

Certificate Format Issues: wget expects PEM format. Convert if necessary:

openssl pkcs12 -in cert.p12 -out client_cert.pem -clcerts -nodes

Missing Private Key: The private key must be either:

  • Included in the PEM file (concatenated)
  • Specified separately via --private-key

Enable verbose SSL output:

wget --debug --verbose \
  --certificate=client_cert.pem \
  https://example.com

Check for these key debug messages:

...
SSL: Certificate verification: OK
SSL: Client certificate: Sent
...

For mutual TLS with intermediate certificates:

wget \
  --certificate=client_cert_and_chain.pem \
  --private-key=client_key.pem \
  --ca-certificate=trusted_cas.pem \
  --certificate-type=PEM \
  --private-key-type=PEM \
  https://mtls.example.org

When dealing with PKCS#12 files directly:

wget \
  --certificate-type=PKCS12 \
  --certificate=client.p12 \
  --password=your_password \
  https://secure.site

If you control the server, verify:

  • The CA used to sign client certificates is properly configured
  • TLS versions match (e.g., not forcing TLS 1.3 when client only supports 1.2)
  • Cipher suites are compatible

When attempting to use client certificates with wget, many developers encounter the frustrating SSL handshake failure error:

HTTP request sent, awaiting response... Read error (error:14094410:SSL routines:
SSL3_READ_BYTES:sslv3 alert handshake failure; error:140940E5:SSL routines:SSL3_
READ_BYTES:ssl handshake failure) in headers.
Giving up.

The error indicates the server rejected the client certificate during TLS negotiation. Common causes include:

  • Incorrect certificate chain configuration
  • Missing private key
  • Certificate format issues
  • Mismatched TLS protocols between client and server

The proper way to specify client certificates with wget requires multiple parameters:

wget --certificate=/path/to/client.crt \
     --private-key=/path/to/client.key \
     --ca-certificate=/path/to/ca.crt \
     https://secure.example.com/api

1. Certificate formats matter: wget typically expects PEM format for all certificates

2. Private key handling: The key must be unencrypted or wget will prompt for password

3. Certificate chain: Include intermediate certificates in your client.crt file

Add verbose output to diagnose issues:

wget --debug \
     --verbose \
     --certificate=client.crt \
     --private-key=client.key \
     https://example.com

If wget continues to fail, consider these options:

1. Convert certificate formats:

openssl pkcs12 -in certificate.pfx -out client.pem -nodes

2. Use curl as alternative:

curl --cert client.crt --key client.key https://example.com

Verify your server is properly configured for client certificate authentication:

  • Check TLS protocol versions supported
  • Verify the CA is properly installed on server
  • Confirm the server expects client certificates