onprema

Demystifying SSL/TLS certificates and OpenSSL commands

First of all, SSL and TLS are often said synonymously. They are similar, but not the same.


Here's a command:

openssl genrsa -aes256 -passout pass:changeme -out server.pass.key 2048

Translation: Use the RSA encryption system to create a private key file, called, server.pass.key, protected by a password of "changeme". Make it 2048 bytes long. Use the AES 256 encryption algorithm to encrypt the contents of the file.

Output:

❯ cat server.pass.key
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ6ZPCcnm7ofhWjwHN
V5....................[...]rfGNwY3QliKgXI4o1/oRvNCJH3Tt4aUGLvXsB
IfNoW6QV4tz+7e/RBpj4J6M00b6czbDPm8IxPqQUjDrvPMye31RM8UIfWxhPonpV
cIGNNLdlH/wQGCvS5ci/v1wsJPKaJ+972H7BoORUDQp3PXqtdSSZdUM=
-----END ENCRYPTED PRIVATE KEY-----

A private key is used to decrypt data and digitally sign things. It should never be exposed.

Side note: OpenSSL automatically derives the public key from the private key when it needs it. In RSA (and other public-key systems), the public and private keys are mathematically related. If you have the private key, you can always calculate what the corresponding public key is. It's like having a master key - you can figure out what the lock looks like.

You can see the public key of a private key by running:

openssl rsa -in server.key -pubout

writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsUGhkFPzxinQY+fcBKPt
gqpO6I1OOGgnS5DkPraNhInws6lW4FhviyDk1FB7Lb2ptktibCp2QxdiUOlCj/RF
Ym[..................ik9+ABRPrwJwIDD8Rx7ZMc4y/G/Q0Mw74edYHtLYd3O
AwIDAQAB
-----END PUBLIC KEY-----

Here's another command:

openssl rsa -passin pass:changeme -in server.pass.key -out server.key

Translation: Working with an RSA key, use the password "changeme" to decrypt an RSA private key file named server.pass.key, and write an unencrypted key file to server.key

This creates an unencrypted private key.

Why do this?

Many applications expect a private key that doesn't need to be unencrypted (which would require entering a password).

Note: if you don't want a password-protected private key, you can just run openssl genrsa -out server.key 2048

Output:

❯ cat server.key
-----BEGIN PRIVATE KEY-----
MIIEvQ...............KG0TXcNQFXwDGMHlLcw4PJiA10ILntn6Zdj1pw5DK+6
gK/D/KjwJqACT/bWZ3u/fFAb8V8MROqebIL/JjnBAoGAA3HGnilR+S3au6VQL0FD
xk0yDuOnAOknFaKAWR4RZst/Y9V6xcVydJiV2PLsmPU8bHdlyiyTE14W7NPiTfUs
67073dHm0CzEnpkpwZblGZtNJNyPdtbhtbJqLtqUzWlX8L9g5JCzCBi4gvAJPS0Q
i60Wixyd63tS2rR/FOIodJ8=
-----END PRIVATE KEY-----

Note: this one says "PRIVATE KEY", instead of "ENCRYPTED PRIVATE KEY".


Here's another command:

openssl req -new -key server.key -out server.csr

Translation: Create a new (-new) certificate request (req) and put a public key (derived from a private key at server.key) in the request. Sign it using the private key. Save the certificate signing request to a file called server.csr.

What is a certificate request?
A mechanism to establish trust between servers and clients who send requests to a domain name. The request is sent to a certificate authority (like Verisign or Let's Encrypt) -> the CA verifies that the requestor owns the domain -> the CA signs the certificate request with their private key and the requestors public key, creating a certificate -> browsers trust the CA, so they trust certificates signed by the CA.

What does it mean to "sign" a request?
It's like a digital fingerprint that proves:

a certificate signing request only needs to be done once per certificate. you can delete the CSR once you get your certificate.

Output:

❯ openssl req -new -key server.key -out server.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:San Francisco
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:thisisimportant.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

This Distinguished Name for is how the CA would do extra verification to determine the requestor is who they say they are. There are validation steps they will take when they need to, for things like government websites.

The CSR file looks like this:

❯ cat server.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIC6TCCAdECAQAwgaMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
MRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMT4wPAYDVQQDDDUqLmxlZS1nYWluZXMt
......................................ALqQO3CW2zexLpR6alD87hW6RR
AfDYdrxRODYH4D/idO4ZWvzKtifyu5h8b/cpbOsC2sgAV4AT10omcSVADEIT6+9a
tcEYlteGyG3Txa/knroU6lrbPkeu8zA9qyKwq2E=
-----END CERTIFICATE REQUEST-----

Here's another command:

openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

Translation: Create a certificate, X-509 formatted, valid for 365 days, using the SHA-256 signature hashing algorithm, reading from the signing request at server.csr, self-sign the certificate using the server.key private key, and output the certificate to a file called server.crt

In this case, I'm acting as my own CA by using the -signkey flag with my own private key instead of a CA key. Browsers should warn you about self-signed certificates! But this is industry-standard for internal applications.

Output:

Certificate request self-signature ok
subject=C=US, ST=California, L=San Francisco, CN=thisisimportant.com

and a file named server.crt.

#security