How to Use the Same SSH Key for Both Git and HTTPS Authentication


3 views

When setting up development environments for distributed teams, authentication becomes a critical pain point. The core challenge emerges from two fundamentally different authentication mechanisms:


# SSH typically uses keys in OpenSSH format
ssh-keygen -t rsa -b 4096 -C "dev@example.com"
# While SSL/TLS expects keys in PKCS#8 or other formats
openssl genrsa -out private.key 4096

SSH keys (RFC 4716) and SSL/TLS keys (PKCS#8/RFC 5958) serve different protocol stacks. SSH keys are typically PEM-encoded with BEGIN RSA PRIVATE KEY headers, while modern SSL prefers PKCS#8 wrapped keys with ENCRYPTED PRIVATE KEY headers.

The most reliable approach is to generate a single key pair and convert between formats:


# Convert SSH private key to PKCS#8 for SSL
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
  -in id_rsa -out ssl_private.key

# Extract public certificate (if needed)
openssl req -new -x509 -key ssl_private.key -out cert.pem -days 365

For Apache HTTPD:


SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/ssl_private.key

For NGINX:


ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/ssl_private.key;

Configure Git to use the same key for SSH:


# ~/.ssh/config
Host git.example.com
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes

For HTTPS client authentication (less common but possible):


# curl example
curl --key ssl_private.key --cert cert.pem https://example.com

While convenient, using the same key across services increases attack surface. Implement these mitigations:

  • Use key passphrases (ssh-keygen -p)
  • Set appropriate file permissions (chmod 600)
  • Regularly rotate keys (consider monthly for teams)

Some SSH servers support x509 certificates. For OpenSSH:


# Server configuration
TrustedUserCAKeys /etc/ssh/ca.pub

This allows using the same SSL certificate for SSH authentication.


When setting up infrastructure for distributed teams, authentication becomes a critical pain point. The fundamental issue stems from SSH and SSL/TLS using different key formats and storage mechanisms:


# SSH typically uses OpenSSH format keys
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACD8W5VW0pC0JdJ4JYH4e6Y7v7X6+3Dp7m7n8kX3jZw7JgAAAJj4xbC6+MWw
ugAAAAtzc2gtZWQyNTUxOQAAACD8W5VW0pC0JdJ4JYH4e6Y7v7X6+3Dp7m7n8kX3jZw7Jg
AAAEB6yTt2vZLXj1Xp5U5o8m7l5vJkYvN9s7r3k1Y5J7j7IPxblVbSkLQl0nglgfh7pju/t
fr7cOnubufyRfeNnDsmAAAAC3Rlc3RAZXhhbXBsZQE=
-----END OPENSSH PRIVATE KEY-----

# While SSL/TLS expects PKCS#8 or PEM format
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDA3W0Q2oPJz8yI
...
-----END PRIVATE KEY-----

The solution involves converting between formats while maintaining security. Here's how to transform an SSH key for HTTPS client authentication:


# Convert OpenSSH private key to PEM format
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in id_ed25519 -out id_ed25519.pem

# Extract public certificate (for SSL/TLS)
openssl req -new -x509 -key id_ed25519.pem -out cert.pem -days 365

For NGINX to accept the client certificate:


server {
    listen 443 ssl;
    ssl_certificate /path/to/server.crt;
    ssl_certificate_key /path/to/server.key;
    ssl_client_certificate /path/to/ca.crt;
    ssl_verify_client optional;

    location / {
        if ($ssl_client_verify != SUCCESS) {
            return 403;
        }
        # Your normal proxy pass or root here
    }
}

Configure Git to use the same key for both protocols:


# ~/.ssh/config
Host git.example.com
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes

# Git HTTPS client cert configuration
git config --global http.https://git.example.com.sslcert ~/.ssh/cert.pem
git config --global http.https://git.example.com.sslkey ~/.ssh/id_ed25519.pem

While convenient, this approach requires careful permission management (0600 for private keys) and regular key rotation. Consider these enhancements:

  • Use hardware security modules (HSMs) for production environments
  • Implement short-lived certificates with automated renewal
  • Combine with OAuth/OIDC for web applications