How to Fix “SSL_CTX_use_PrivateKey_file: key values mismatch” Error When Installing SSL Certificate with Intermediate Chain on Nginx


2 views

The error SSL_CTX_use_PrivateKey_file failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch) occurs when Nginx cannot match the private key with the certificate you're trying to use. This typically happens when:

  • The private key doesn't correspond to the certificate
  • The certificate chain is improperly configured
  • Files were modified after generation

First, let's verify if the private key matches the certificate:

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

Both commands should output the same MD5 hash. If they don't, you're using mismatched key-certificate pair.

Many developers make these errors when working with SSL certificates:

  1. Combining certificates in wrong order (should be: domain cert first, then intermediates)
  2. Using wrong file extensions (.crt vs .pem vs .key)
  3. Not including full certificate chain

Here's a proper configuration example for Gandi SSL certificates:

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /etc/nginx/ssl/mydomain-bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/mydomain.key;
    
    # Recommended SSL settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256...';
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # Your other configuration...
}

For Gandi certificates, the bundle should contain:

# Domain certificate
-----BEGIN CERTIFICATE-----
(Your domain certificate)
-----END CERTIFICATE-----

# Intermediate certificate
-----BEGIN CERTIFICATE-----
(CA's intermediate certificate)
-----END CERTIFICATE-----

# Optional: Root certificate (usually not needed)
-----BEGIN CERTIFICATE-----
(Root certificate if required)
-----END CERTIFICATE-----

If you're still experiencing issues:

1. Check file permissions:

chmod 600 /etc/nginx/ssl/mydomain.key
chmod 644 /etc/nginx/ssl/mydomain-bundle.crt

2. Test Nginx configuration before restarting:

nginx -t

3. Verify certificate chain with OpenSSL:

openssl verify -untrusted GandiStandardSSLCA.pem mydomain.crt

The error message SSL_CTX_use_PrivateKey_file failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch) indicates that Nginx cannot verify the private key matches your SSL certificate. This commonly occurs when:

  • The private key doesn't correspond to the certificate
  • The certificate chain is improperly concatenated
  • File permissions prevent proper key reading

First, confirm your private key matches the certificate using OpenSSL:

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

If the MD5 hashes differ, you're using mismatched files. You'll need to either:

  1. Regenerate a CSR and reissue the certificate
  2. Locate the correct private key that generated the CSR

For Gandi certificates, the correct chain order should be:

cat mydomain.crt GandiStandardSSLCA.pem > mydomain-bundle.crt

Verify the chain integrity:

openssl verify -CAfile GandiStandardSSLCA.pem mydomain.crt

Here's a proper vhost configuration example:

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /etc/nginx/ssl/mydomain-bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/mydomain.key;
    
    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384...';
    
    # Other security headers
    add_header Strict-Transport-Security "max-age=63072000" always;
}

Ensure proper file permissions:

chmod 600 /etc/nginx/ssl/mydomain.key
chmod 644 /etc/nginx/ssl/mydomain-bundle.crt
chown root:root /etc/nginx/ssl/*

For advanced troubleshooting, test the SSL connection:

openssl s_client -connect example.com:443 -showcerts

This will display the complete certificate chain being presented, helping identify any missing intermediates.