What is the difference between a certificate and a key-pair ?
A certificate is like a driver's license: some authority says your identity is X.

A key-pair can be used to do a signature (message M came from someone who knows the private key) or an envelope (message N can be read only by someone who knows the private key).

Steve Cope's "SSL and SSL Certificates Explained For Beginners"
Mike Malone's "Everything you should know about certificates and PKI but are too afraid to ask"

From Eric Rescorla article:
In order to have a secure connection to a web site via HTTPS, it is necessary to both encrypt the traffic and authenticate the site. The encryption happens via TLS, but TLS depends on the server having a public key which is authenticated via a certificate. The certificate in turn binds that key to the server's identity. The server uses the private key associated with that public key to complete the TLS handshake, thus proving that it is the correct owner of that identity. Without the certificate, your browser could just be forming a secure connection to an attacker.

These certificates are issued by certificate authorities (CAs), who are responsible for validating the server's identity, issuing the certificate, and revoking it if something goes wrong (e.g., the server's key is compromised). ...


The way things work in practice is that the client has a list of CAs that it trusts to issue certificates ...

From Mike Malone article:
... the goal of certificates and PKI is to bind names to public keys.


Authentication, in general, is the process of confirming the truth of some claim.


A signature can be verified using a public key but can only be generated with a corresponding private key. Thus, a recipient that only has a public key can verify signatures, but can't generate them. ...


There are two things you can do with a key pair:
  • You can encrypt some data with the public key. The only way to decrypt that data is with the corresponding private key.

  • You can sign some data with the private key. Anyone who knows the corresponding public key can verify the signature, proving which private key produced it.

... public key cryptography lets one computer (or bit of code) prove to another that it knows something without sharing that knowledge directly. ...


What if you don't already know my public key? That's what certificates are for.

Certificates are fundamentally really simple. A certificate is a data structure that contains a public key and a name. The data structure is then signed. The signature binds the public key to the name. The entity that signs a certificate is called the issuer (or certificate authority) and the entity named in the certificate is called the subject.


... if you've never met some computer before, but you trust some certificate authority, you can use a certificate for authentication: verify that the certificate is valid (check signature, etc), look at public key, "look at private key" [communicate with owner of private key ?] across network, read name.


Web PKI ... defines what a "name" is and where it goes in a certificate, what signature algorithms can be used, how a relying party determines the issuer of a certificate, how a certificate's validity period (issue and expiry dates) is specified, how revocation and certificate path validation works, the process that CAs use to determine whether someone owns a domain, and a whole lot more.

Web PKI is important because Web PKI certificates work by default with browsers and pretty much everything else that uses TLS.

Internal PKI is PKI you run yourself, for your own stuff: production infrastructure like services, containers, and VMs; enterprise IT applications; corporate endpoints like laptops and phones; and any other code or device you want to identify. It allows you to authenticate and establish cryptographic channels so your stuff can run anywhere and securely communicate, even across the public internet.

Why run your own internal PKI if Web PKI already exists? The simple answer is that Web PKI wasn't designed to support internal use cases. ...

Further, with Web PKI you have little or no control over important details like certificate lifetime, revocation mechanisms, renewal processes, key types, and algorithms ...

Finally, the CA/Browser Forum Baseline Requirements actually prohibit Web PKI CAs from binding internal IPs ...


... "how does the relying party know the issuer's public key?""

The answer is simple, if not satisfying: relying parties are pre-configured with a list of trusted root certificates (or trust anchors) in a trust store. The manner in which this pre-configuration occurs is an important aspect of any PKI. ...

So where do trust stores come from? For Web PKI the most important relying parties are browsers [and operating systems] ...

... if you run your own internal PKI you should maintain a separate trust store for internal stuff. ...


... the subject alternative name (SAN) X.509 extension to bind a name in a certificate.

There are four sorts of SANs in common use, all of which bind names that are broadly used and understood: domain names (DNS), email addresses, IP addresses, and URIs. ...

What is the difference between PGP keys, SSH keys, and SSL keys?
on reddit:
The only difference is the types of programs they're used for (PGP usually for email or encrypted messages, SSH usually for securing remote connection to computers, SSL usually for running a website or anything else done over SSL), but besides that they're the same keys just wrapped in a different container.


PGP is mostly used for text messages between people, like email. You typically send the decoding key out to people, and a lot of people might have it. Or you might make it public so everyone has it, and it doesn't really encrypt anything, but proves you are really you, since you are able to 'sign' things.

SSH is generally to talk one machine to one other machine. If you want your laptop to connect to one linux server you make one SSH for key. Multiple computers can use the same key and it works, but the idea is one to one. You download it and one computer can talk to another computer.

SSL is good for automatic connections. Anyone can go up to an encrypted website and get a key to talk to it, so no one else can read what you are doing with it, but it'll give one to anyone.


There's another difference not mentioned yet: in SSH, the keys are used on their own, but in SSL (really TLS these days) there's also a certificate, which is the public key with some information about the subject, bound together by being signed with the private key.


These are not different kinds of encryption, they are different protocols that give other people the information they need to understand how they can decrypt or verify your message. They may allow for an array of different options for exact cryptographic algorithm, which is important so that we can upgrade to more secure ones over time, or fix bugs. The connection protocols, TLS and SSH, also have some kind of negotiation built in, so that the machines can understand each other and perform key exchange.

PGP (1991): Pretty Good Privacy, designed for digital signatures and encryption for individual messages, such as emails. You might be using this somewhere without knowing about it, e.g. it might be used to sign your emails.

SSL (1994)/TLS (1999): Secure Socket Layer/Transport Layer Security, protocol for encrypted connections, also allowing for proof of identity with digital certificates. Best for public-facing web servers, to the point that all of your web traffic goes over TLS now, browsers will warn you if it is not.

SSH (1995): Secure SHell, secure machine-to-machine command-line protocol, which includes logging into a user account. Similar, in principal, to SSL, but higher-level and more advanced and allows all machines to interface with each other at the command-line level. You probably won't use SSH unless you are a developer, the most common use is SFTP (which is basically just running the FTP protocol inside an SSH connection.)

Semi-humorous: Carl Tashian's "If OpenSSL were a GUI"

Web Certificates

Pieter Arntz's "What are SSL certificates?"
Mike Malone's "Everything you should know about certificates and PKI but are too afraid to ask"
Amit N. Bhagat's "Digital Certificates Explained"
Eric Rescorla article
Supratim Samanta's "Deep Dive into SSL certificates"
SoByte's "PKI Systems and CA"
CREDO23's "Understanding SSL/TLS"

J Schauma's "Debugging Certificate Errors"
Jussi Pakkanen's "Getting web proxys and certificates working on Linux"
Let's Encrypt's "Challenge Types"

Chris Siebenmann's "TLS increasingly exists in three different worlds"
Chris Siebenmann's "The 'web' TLS world is different from the non-public one in practice"
See supported TLS and SSL ciphers (versions):
"openssl ciphers -v | awk '{print $2}' | sort | uniq"

How HTTPS works:
  1. Browser sends HTTP request to web server on port 443.
  2. Server sends site's public key (as a certificate) to the browser.
  3. Browser verifies the public key by using local cert it has for the CA that signed the web site's cert.
  4. Browser checks CA's revocation list to see if site's cert has been revoked.
  5. Browser generates a random key (session key) to use for this connection.
  6. Browser encrypts the random key with the site's public key and sends it to the site's server.
  7. Site's server decrypts the content with the locally-stored private key, to obtain the browser-generated session key.
  8. Browser and site start to talk using the session key with symmetric encryption (such as AES), where both parties use the same key to encrypt and decrypt.
SoByte's "Understanding HTTPS principles, SSL/TLS protocols in detail"
SoByte's "What happens in a TLS handshake?"

At startup, will any of the browsers report "hey, a new certificate was installed since last time the browser was running" ? I think they should.

Will any of the browsers report "hey, one of your personal certificates is about to expire" ? I think they should. I can't find any Firefox or Chrome extension that does this.

As far as I can tell, Firefox and Chrome give no API for an extension to access installed certificates.

Some questionable certs may appear under "Authorities": a couple from China, DigiNotar. Various CA's have been hacked from time to time. Firefox is in process of removing trust for Symantec-issued certs.

Certs that appear under "Servers" reveal a little bit about your browsing history: they may show what domains you've visited.

As far as I know, there is no downside to removing Server certificates, and removing a few Authorities is okay too (as long as you don't remove them all).

Ctrl blog's "Installing VPN root certificates leaves you more vulnerable to snooping"
Pieter Arntz's "When you shouldn't trust a trusted root certificate"
Hanno Bock's "Check for bad certs from Komodia / Superfish"

List root certificates (article):
Ubuntu family:
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' </etc/ssl/certs/ca-certificates.crt
Red Hat family:
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' </etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

Trusted certificate stores

Security certificates can be stored in a number of places ?
  • System store. /usr/local/share/ca-certificates/

  • In some browsers. /usr/share/ca-certificates/mozilla/

  • NSS database.
    certutil -d sql:$HOME/.pki/nssdb -L
    certutil -d sql:$HOME/.pki/nssdb -L -n CERTNICKNAME
    Chromium Docs - Linux Cert Management

  • In other mini-browser-containing apps such as Thunderbird email client ? ~/.thunderbird/PROFILENAME/cert9.db and key4.db ?

  • Electron apps contain the Chromium browser engine; what certificate store is used, or none ?

  • Node.js comes with a built-in store of CA's ?

  • Java has its own store ? Also each Java app could have its own ? /etc/ssl/certs/java/cacerts, jre/lib/security/cacerts ? "man keytool" article

  • Python: python3/dist-packages/requests/cacert.pem python2.7/site-packages/requests/cacert.pem

  • CUPS: /etc/cups/ssl

  • LDAP or OpenLDAP ?

  • System store used by openssl (/etc/ssl):
    # find the base directory:
    openssl version -d
    # list the certs:
    ls -R `openssl version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/'`/cert*
    # or maybe
    sudo ls -lAR /etc/ssl
    # or
    sudo find /etc/ssl -name '*.pem' -print | xargs -I{} openssl x509 -subject -noout -in {}
    sudo find /etc/ssl -name '*.crt' -print | xargs -I{} openssl x509 -subject -noout -in {}
    sudo find /etc/pki -name '*.pem' -print | xargs -I{} openssl x509 -subject -noout -in {}
    # but my personal certs (installed in browsers etc) don't show up in there
    man update-ca-certificates
    ls -l /etc/ssh
    ls -lAR ~/.pki
    ls -lAR /etc/pki
    # while user is logged in:
    sudo ls -lAR /run/user/USERIDNUMBER/keyring

From someone on Stack Exchange:
Most distros put their certificates soft-link in system-wide location at /etc/ssl/certs.
  • Key files go into /etc/ssl/private
  • System-provided actual files are located at /usr/share/ca-certificates
  • Custom certificates go into /usr/local/share/ca-certificates
Whenever you put a certificate in one of the above mentioned paths, run "update-ca-certificates" to update /etc/ssl/certs lists.

From someone on reddit 11/2019:
Applications that utilize the system cert store: Chrome on macOS/windows [but 11/2020 Chrome is changing to have its own store: article]. Safari on macOS. Edge on windows [old Edge, I assume; don't know about new Edge]. Linux support depends on the distribution. RHEL is probably better than others.

Firefox uses its own key store ...

Java applications will vary in support. It really depends on the implementer.

[Certs can be stored in a hardware device:] A Yubikey with certs provisioned acts as a pkcs#11 device which is an industry standard interface to cryptographic devices. It has good support for all applications that utilize the system cert store. There are plugins to utilize pkcs11 devices for Firefox.

By default, Okular in KDE will link to Firefox's cert store.

Federal Public Key Infrastructure Guides' "Trust Stores"
Venam's "Key And Trust Store on Unix-like OS"
James Force's "How to configure your CA trust list in Linux"

Can browser use certs installed into central OS store ?
Apparently Chrome and Edge do that, and Firefox on Windows and MacOS can be configured to do so.
Mozilla's "Expanding Client Certificates in Firefox 75"

Where are certs stored ?

ls /etc/ipsec.d/cacerts
ls /usr/share/ca-certificates
ls /usr/share/ca-certificates/mozilla
ls /etc/pki
ls -l /usr/local/share/ca-certificates
ls -l ~/.mozilla/firefox/*.default-release/cert*
locate .pem   # finds files everywhere
sudo ls -l /etc/ssl/private   # key files
openssl version -d      # usually says "/etc/ssl"

# Symlinks to cert files in other dirs.
# Updated by running "update-ca-certificates".
ls /etc/ssl/certs

# To get the "subject" of every CA certificate in /etc/ssl/certs/ca-certificates.crt:
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' </etc/ssl/certs/ca-certificates.crt

# List all certs in system and display issuer and expiration date:
locate .pem | grep "\.pem$" | xargs -I{} openssl x509 -issuer -enddate -noout -in {}

# System CAs ?
trust list --filter=ca-anchors
ls /etc/pki/ca-trust/source/whitelist/

# Java certificates:
keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts

# Firefox certificates:
cd $HOME/.mozilla/firefox/PROFILEDIR     # where cert9.db file is
certutil -L -d .             # list all certs
certutil -K -d .             # list nicknames of certs
certutil -O -d . -n NICKNAME # show info about a cert

# NSS certificate store, maybe openSUSE only, used by Firefox and Evolution and Network Manager ?
ls $HOME/.local/var/pki/nssdb/

# man openssl-x509
# check for certs expired or due to expire in next month (30*24*60*60 == 2592000 seconds)
for f in `ls /etc/ssl/certs/*.pem`
	openssl x509 -checkend 2592000 -noout -in "$f" >/dev/null
  if [ $? -ne 0 ]
	  openssl x509 -issuer -enddate -noout -in "$f"

# See certs used to make a connection:
openssl s_client -showcerts -connect DESTDOMAIN:443

# Snap version of sqlitebrowser fails, don't use it.
sudo apt install sqlitebrowser
sqlitebrowser --help

sqlitebrowser --read-only --table nssPublic ~/.mozilla/firefox/*.default-release/cert9.db
# Personal certs are listed among the others.
# The interesting data is in a blob in column a11, I think.
# But I think this is a cache; not all certs are listed.

# man openssl-pkcs12
locate .p12 .pfx
openssl pkcs12 -in CERTNAME.p12 -out TMP.pem -nodes -clcerts
openssl x509 -issuer -enddate -checkend 2592000 -noout -in TMP.pem
rm TMP.pem
openssl pkcs12 -info -nodes -in CERTNAME.p12

# Check a certificate in a crt file:
openssl x509 -in CERTNAME.crt -text -noout

# Check a certificate in a der file:
openssl x509 -in CERTNAME.der -inform der -text

openssl verify CERTNAME.*     # any file type

# A .pfx file has both public and private PKCS12 keys, can contain multiple certs, can be password-protected.
# A .p12 file has both public and private PKCS12 keys, can contain multiple certs, can be password-protected.
# .pfx is predecessor of .p12
# A .key file has both public and private PKCS8 keys, in either DER binary or PEM ASCII format.
# A .cer file has only public key, in either DER binary or PEM ASCII format.
# A .crt file has only public key, in either DER binary or PEM ASCII format.
# A .der file has only public key, in DER binary format.
# A .pem file has only public key, in Base-64 and with a header and footer added.
# A .ca-bundle file has only public key, what format ?
# A .pvk file has only private key.


Ubuntu's "SSH / OpenSSH / Installing Configuring Testing"
Chris Hoffman's "How to Secure SSH with Google Authenticator's Two-Factor Authentication"
Linuxaria's "Add security to your ssh daemon with PAM module"
nixCraft's "Top 20 OpenSSH Server Best Security Practices"
Carl Tashian's "SSH Agent Explained"

From "man ssh":
"The idea is that each user creates a public/private key pair for authentication purposes. The server knows the public key, and only the user knows the private key. ssh implements public key authentication protocol automatically ..." and "A variation on public key authentication is available in the form of certificate authentication: instead of a set of public/private keys, signed certificates are used. This has the advantage that a single trusted certification authority can be used in place of many public/private keys."
Also relevant "man ssh-keygen".

From Ravi Saive's "How to Setup Two-Factor Authentication (Google Authenticator) for SSH Logins":
"Important: The two-factor authentication works with password-based SSH login. If you are using any private/public key SSH session, it will ignore two-factor authentication and log you in directly."

SK's "How To Configure SSH Key-based Authentication In Linux"
Alistair Ross's "How To Set Up SSH Keys"
Carla Schroder's "5 SSH Hardening Tips"
Smallstep's "A Deeper Look into SSH and X.509 Certificates"

Testing your SSH from outside:
InfoByIp's "SSH server connectivity test"
Rebex SSH Check
But really you need to try to connect from an outside machine and see what happens.

Jesus Vigo's "How to join a Linux computer to an Active Directory domain"

Certificate Formats


From GlobalSign /Julie Olenski article:
Historically there have been four algorithms in a cipher suite:
  • Key Exchange.
  • Digital Signature.
  • Message Authentication.
  • Hashing Algorithm.

Gaurav Kamathe's "Encrypting and decrypting files with OpenSSL"