Transforming Privileged Access: A Dialogue on Secretless, Zero Trust Architecture
Mar 28
Virtual
Register Today
Teleport logo

Teleport Blog - SSH Certificates: How Do OpenSSH Certificates Compare to X.509? - Jun 23, 2022

SSH Certificates: How Do OpenSSH Certificates Compare to X.509?

X.509 vs. OpenSSH Certificates

X.509 is the first thing that comes to mind when discussing digital certificates. After all, it is the most widely used digital certificate in the PKI ecosystem and is the core component of SSL/TLS protocols, the technology that powers HTTPS. X.509 was first released on 25 November 1988 and is powerful, extensible and widely supported. But it's not the only certificate format available out there. For example, the popular email encryption program PGP uses a custom certificate format instead of X.509. And PGP is not the only one to avoid X.509 — the most widely used remote access server OpenSSH also uses a custom certificate format. They call it certkeys!

OpenSSH has supported certificate-based authentication since version 5.4, but despite X.509 being widely supported, OpenSSH did not base the certificates in X.509 format but instead invented a simple but capable and compatible enough format for certificate-based authentication. Why? It is questionable, but the reasons must have been well-founded for sure!

In this blog post, we will explore how OpenSSH's certificate compares with X.509, including a few strengths and weaknesses of the OpenSSH implementation.

Why OpenSSH implements a custom format instead of X.509

The implementation details of OpenSSH certificate-based authentication are well-described in the PROTOCOL.certkeys document, but I'll highlight the important points below:

Simple extension to existing public-key authentication

Let's first try to understand how OpenSSH implements certificate-based authentication. In OpenSSH, the CA certificate is just public and private key pairs with additional identity and constraints data. The private key of the CA is used to sign user and host (SSH server) certificates. Once the keys are signed, they are distributed to users and hosts, respectively. The public key of the CA is copied to the SSH server, which is used to verify the user's certificate.

For user authentication, the SSH client presents the user certificate (signed by CA) to the SSH server in each new SSH connection. The SSH server validates the certificate by checking it against the CA's public key. Along with the signature validation, the server will also check if the user certificate is not expired and if it violates security constraints. Access is granted upon successful validation of the certificate.

This authentication flow is similar to public-key authentication with just additional verification of trust based on a signature signed by a trusted CA and additional constraints of expiry dates and identity attributes. Under the hood, this logical extension means that implementation for certificate-based authentication became as simple as extending the public-key authentication protocol as specified in RFC 4252. This is done via SSH protocol extension and adding new keys for certificates including following key types:

# cert key types
ssh-rsa-cert-v01@openssh.com
ssh-dss-cert-v01@openssh.com
ecdsa-sha2-nistp256-cert-v01@openssh.com
ecdsa-sha2-nistp384-cert-v01@openssh.com
ecdsa-sha2-nistp521-cert-v01@openssh.com
ssh-ed25519-cert-v01@openssh.com

# SHA-2 signatures
rsa-sha2-256-cert-v01@openssh.com
rsa-sha2-512-cert-v01@openssh.com

Reduced attack surface

Keeping the certificate format minimal helps reduce the attack surface. X.509 is a behemoth when it comes to certificate attributes and extensibility. Supporting X.509 certificates means implementing full-fledged X.509 PKI. Given X.509 is designed to be universal, as such it carries loads of features that simply may not be required for SSH authentication. Reducing attack surfaces is always a welcomed approach for maintaining high security.

Reduced dependencies on external crypto libraries

This is not explained in the design document shared above, but I've seen this mentioned many times in discussion forums. Historically, OpenSSH crypto libraries were all based on OpenSSL's crypto library, and as such, any feature sets on the OpenSSH protocol should be first supported by OpenSSL. Implementing a custom format allows OpenSSH to maintain and support better solutions without the need to wait for implementations upstream.

Enforce better security by default

Custom implementations allow OpenSSH to support best practices for CA and certificate management. Maintaining separate CA for a user and host authentication is an expected workflow in OpenSSH. Algorithms such as AES, ChaCha20, RSA, ECDSA, and Ed25519 are readily available.

Limitation of OpenSSH certificates over X.509

Simplicity comes with a price! OpenSSH certificates lack the broader customizability that X.509 supports.

One additional Certificate Authority (CA) to maintain

X.509 are widely supported, so chances are that your organization already maintains trust with an internal or external X.509 CA. But to support certificate-based authentication, you will need to maintain another CA that can handle SSH certificate signing and issuance.

Misses X.509 features such as cross-signing and CA hierarchy

OpenSSH has no mechanism to support cross-signing CA and managing multiple CA hierarchies besides the notion of user and host CA certificates. This can pose a challenge in a large-scale implementation where multiple intermediate CA can come in handy during CA rotation or CA migration.

Comparing X.509 properties with OpenSSH certificate

Below is a high-level overview of X.509 and OpenSSH certificate properties.

X.509 CertificateOpenSSH Certificate
Use CaseMostly universal. SSL/TLS, S/MIME, EAP-TLS etc. Can be used with SSH protocol. Only for SSH
Key generation algorithmsDDSA, RSA, EcDSA, EdDSA (limited support)DSA, RSA, ECDSA, EDDSA
Signature algorithmsMD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512. MD2, MD5 and SHA-1 are considered insecure and should be avoided.SHA-256, SHA-512
Certificate Extensibility (attaching additional metadata)Using certificate extensionUsing certificate extension
Certificate encoding formatPEM, DERCustom public key format. Can be exported as PEM.
Popular Tools to generate certificateOpenSSL client tool and libraries, X.509 compatible libraries.ssh-keygen, SSH libraries. ssh-keygen uses OpenSSL under the hood.

Let’s look at a sample OpenSSH certificate created using OpenSSH ssh-keygen below:

$ ssh-keygen -t rsa -b 4096 -f user_ca -C user_ca
$ ssh-keygen -f user-key -b 4096 -t rsa
$ ssh-keygen -s user_ca -I test@example.com -n ec2-user,testuser -V +365d user-key.pub
$ ssh-keygen -L -f user-key-cert.pub
user-key-cert.pub:
       Type: [email protected] user certificate
       Public key: RSA-CERT SHA256:O83ldxrIWTNs1z0WIl7FgPuA+wDbRuAmczCE1kulSzQ
       Signing CA: RSA SHA256:UOAJbRtvHSHtVa2URVaDKBDpmbDbXqWB3QOFqF7Nhj4 (using rsa-sha2-512)
       Key ID: "[email protected]"
       Serial: 0
       Valid: from 2022-06-17T11:22:00 to 2023-06-17T11:23:04
       Principals:
               ec2-user
               testuser
       Critical Options: (none)
       Extensions:
               permit-X11-forwarding
               permit-agent-forwarding
               permit-port-forwarding
               permit-pty
               permit-user-rc

Let’s look at a sample X.509 certificate created using OpenSSL below:

$ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
$ openssl x509 -in certificate.pem -text -noout
Certificate:
   Data:
       Version: 1 (0x0)
       Serial Number: 12109341941902761246 (0xa80d06568eda5d1e)
   Signature Algorithm: sha256WithRSAEncryption
       Issuer: C=NP, ST=KTM, L=BSN, O=TestHQ, OU=TestTestHQ, CN=TTQ/emailAddress=test@example.com
       Validity
           Not Before: Jun 17 05:33:40 2022 GMT
           Not After : Jun 17 05:33:40 2023 GMT
       Subject: C=NP, ST=KTM, L=BSN, O=TestHQ, OU=TestTestHQ, CN=TTQ/emailAddress=test@example.com
       Subject Public Key Info:
           Public Key Algorithm: rsaEncryption
               Public-Key: (4096 bit)
               Modulus:
                   00:cd:19:12:99:b9:9b:55:8f:2c:91:b4:58:e7:c6:
                   e5:8b:62:af:33:12:a7:d1:c3:a6:28:2b:17:2b:72:
                   ...
                   cc:49:e8:c4:ea:af:f8:3f:92:79:d9:18:0b:2e:c2:
                   ef:c1:81
               Exponent: 65537 (0x10001)
   Signature Algorithm: sha256WithRSAEncryption
        2c:59:7b:d0:4e:e0:e6:c7:29:d6:55:c6:1b:22:70:3e:20:a3:
        10:9b:ea:4c:2d:39:41:70:69:cf:eb:33:0a:78:9f:69:bd:90:
        ...
        0b:71:95:0d:41:e8:fe:ca:9a:cc:15:dc:0c:6c:7f:3d:93:06:
        1b:31:63:69:1e:24:4d:70

Conclusion

In this post, we explained why OpenSSH implements its own certificate format and how it differs from X.509 standard. The OpenSSH implementation is simple enough to cater to the requirements of certificate-based authentication as implemented by OpenSSH. But maintaining two different types of CA can be challenging for organizations. Should OpenSSH ultimately support X.509? I like the fact that it's simple yet secure enough with a reduced attack surface.

Read our other blog post on SSH keys and certificates:

Automate X.509 and OpenSSH CA management with Teleport

Teleport implements both X.509 and OpenSSH CA management which makes it easy to manage certificate-based authentication in both small and large-scale infrastructure deployments.

Learn how Teleport works! And join our Slack channel to discuss infrastructure access and Teleport.

Tags

Teleport Newsletter

Stay up-to-date with the newest Teleport releases by subscribing to our monthly updates.

background

Subscribe to our newsletter

PAM / Teleport