How, if at all, do SSH keys differ from asymmetric keys used for other purposes?

  • SSH keys are just plain RSA, DSA, or ECDSA asymmetric key pairs. Such a keypair generated by OpenSSH can already be used by OpenSSL and most other programs.

    (The .pub file output by ssh-keygen is in OpenSSH-specific format, but that is irrelevant since the "private" file already contains both private and public keys.)

    Other SSH software may have their own storage formats, such as RFC 4716 or PuTTY's PPK, but they store the same RSA/DSA/ECDSA information.

  • X.509 (used by SSL, S/MIME) is slightly more complicated: the "private" key is still the same, but instead of a bare public-key file you have a "certificate" – an ASN.1 structure containing the public key, subject and issuer names, validity dates. In X.509 v3 certificates, extensions such as "key usage" and "alternate subject name" will be present. The entire certificate is signed by the issuer's key (or self-signed if there is no separate issuer).

    You can easily use an X.509 "private key" file for SSH – OpenSSH even uses the same format.

    You can create an X.509 certificate from a simple keypair and then self-sign it, or you can create a "certificate request" and submit it to be signed by a CA (certification authority).

    To display the information in an X.509 certificate, use:

     certtool -i < foo.pem
     certtool -i --inder < foo.crt
    
     openssl x509 -noout -text < foo.pem
     openssl x509 -noout -text -inform der < foo.crt
    

    (certtool is part of GnuTLS.)

  • OpenPGP (used by GPG) keys are the most complicated. What you call a "PGP key" or "PGP keypair" is a complex structure called an "OpenPGP certificate", containing:

    • one "primary key" – an asymmetric key pair, usually used for signing
    • one or more "user IDs" – textual labels, usually in the form of "Name <email@address>"
      • at least one of them is marked as "primary user ID"
      • for each user ID, a "self-signature" – signature by your own primary key
      • for each user ID, zero or more "signatures" by other users
      • the self-signature packets also contain your preferred algorithms (SHA-1, AES, etc.)
    • one or more "subkeys" – additional key pairs, the first is usually for encryption
      • for each subkey, a signature by the primary key
    • zero or more "photo IDs" – JPEG or PNG attachments containing your face
      • signed the same way as user IDs
    • zero or more X.509 certificates

    All keypairs have expiration dates and usage bits: sign data, certify (sign) keys, encrypt, authenticate to services. The primary key by default has "sign" and "certify" bits and the first subkey is to "encrypt". If you add an "authentication" subkey, you can use it through gpg-agent for SSH authentication.

    To see what your certificate contains:

     gpg --export [email protected] | gpg -vv
    
     gpg --export [email protected] | certtool --pgp-certificate-info
    

    (certtool is part of GnuTLS.)


X.509 certificates and their associated private keys come in several formats:

  • DER is a binary encoding of an ASN.1 structure of the certificate. Such files usually have .crt or .cer file name extensions (.der is less common but not unseen).

  • "PEM" format files contain the same DER-encoded data, but additionally encoded using Base64 and between "BEGIN THIS" and "END THAT" headers. A common filename extension is .pem, although both .crt and .cer are sometimes used here too (but never .der).

  • For private keys belonging to the certificates, "PEM" format is usually used – Base64 surrounded by headers "BEGIN PRIVATE KEY" (key in a PKCS#7 structure) or "BEGIN RSA (or DSA) PRIVATE KEY" (bare key, OpenSSL format). Sometimes the key is in a separate .key file, sometimes it's bundled with the certificate.

  • PKCS#12 and the slightly older PFX are encrypted containers storing both the certificate and the private key (often the issuer's certificate too). This format is used by most software when exporting or "backing up" certificates with private keys.

A less confusing situation is in OpenPGP: all data follows the same binary format, and is optionally "armored" (encoded with Radix64 and between PEM-like headers).


Stored in different places and in different formats (the formats used by PGP, GnuPG, ssh, and several different X.509 formats, among others, are quite different). It is possible to transcode between them to some extent by mixing and matching the right options to ssh-keygen, pgp, gpg/gpg2, openssl, etc.; but in general it's not worth the effort. Also, different key formats support different amounts of information, with ssh carrying the least extra information and X.509 PEM and DER formats carrying the most. Additionally, the OSX Keychain is simply encrypted key/value storage, so a different mechanism is generally needed by each application to convert between the program's native key + metadata format and something that can be stored in the Keychain. (Similar concerns apply to the KDE wallet and GNOME keychain.)