How to Fix “SSL peer was unable to negotiate an acceptable set of security parameters” Error in Apache with Self-Signed Certificates


5 views

When setting up HTTPS on Apache with self-signed certificates, you might encounter the frustrating error:

SSL peer was unable to negotiate an acceptable set of security parameters
(Error code: ssl_error_handshake_failure_alert)

This typically occurs after fixing the initial ssl_error_rx_record_too_long error by properly configuring your SSL files.

Your Apache SSL configuration should include these essential directives:

SSLEngine On
SSLCertificateFile "/path/to/server.crt"
SSLCertificateKeyFile "/path/to/server.key"
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
SSLHonorCipherOrder on

The handshake failure usually stems from one of these issues:

  • Mismatched certificate and private key
  • Missing intermediate certificates
  • Incompatible SSL/TLS versions between client and server
  • Unsupported cipher suites
  • Incorrect file permissions

1. Verify certificate-key pair:

openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5

The MD5 hashes must match.

2. Check SSL configuration syntax:

apachectl configtest

3. Test SSL connection:

openssl s_client -connect yourdomain.com:443 -showcerts

Here's a tested configuration that works with modern browsers:

<VirtualHost *:443>
    ServerName yourdomain.com
    DocumentRoot "/var/www/html"
    
    SSLEngine on
    SSLCertificateFile "/etc/ssl/certs/server.crt"
    SSLCertificateKeyFile "/etc/ssl/private/server.key"
    SSLCertificateChainFile "/etc/ssl/certs/ca-bundle.crt"
    
    SSLProtocol TLSv1.2
    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
    SSLHonorCipherOrder on
    
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains"
    Header always set X-Frame-Options DENY
    Header always set X-Content-Type-Options nosniff
</VirtualHost>

For development environments, generate certificates properly:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key -out server.crt \
-subj "/C=US/ST=State/L=City/O=Company/CN=yourdomain.com"

Modern browsers have strict requirements:

  • Firefox requires SAN (Subject Alternative Name) in certificates
  • Chrome enforces certificate transparency logging
  • Safari has specific CA root requirements

When setting up self-signed certificates for Apache, the "SSL peer was unable to negotiate an acceptable set of security parameters" error typically occurs due to mismatched SSL/TLS configuration between the server and client. In your case, Firefox is rejecting the handshake because the cryptographic parameters can't be agreed upon.

First, verify your certificate chain is properly configured:

openssl verify -CAfile /etc/httpd/conf/ssl/ca.crt /etc/httpd/conf/ssl/server.crt

If this fails, your certificate isn't properly signed by your CA.

Your httpd-ssl.conf needs proper SSL protocol settings. Here's a recommended configuration:

SSLEngine on
SSLCertificateFile "/etc/httpd/conf/ssl/server.crt"
SSLCertificateKeyFile "/etc/httpd/conf/ssl/server.key"
SSLCertificateChainFile "/etc/httpd/conf/ssl/ca.crt"

# Modern compatibility configuration
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5:!RC4:!3DES
SSLHonorCipherOrder on

Use OpenSSL to test the handshake from the server side:

openssl s_client -connect localhost:443 -CAfile /etc/httpd/conf/ssl/ca.crt

And from a remote client:

openssl s_client -connect yourdomain.com:443 -showcerts

1. Missing intermediate certificates
2. Certificate subject name mismatch with domain
3. Incorrect file permissions (key files should be 600)
4. System time being incorrect

In Firefox, access about:config and search for "security.tls.version". Ensure TLS 1.2 or higher is enabled. You can also check the error details in Firefox's Web Console (Ctrl+Shift+K).

Try this cURL command to test the connection:

curl -v --cacert /etc/httpd/conf/ssl/ca.crt https://yourdomain.com

After making changes, always test your configuration before restarting Apache:

apachectl configtest

Then gracefully restart Apache:

apachectl graceful