L0050 Self Signed Key

Self signed key is useful when we want to protect communication between two devices that are under our control. In this case there is no "mutual friend" ( Certificate Authority ) that will sign our certificate.

As a result, we will get one private key and 1 certificate. Our private key will be used to sign a certificate.

Self Signed RSA Key

This is OpenSSL command that will create RSA private key and self signed certificate. Let's dissect this command.
cd /home/fff/Desktop
openssl req -x509 -sha256 -noenc -days 365 -newkey rsa:2048 -keyout private.key -out certificate.crt

req -x509This command is asking for creation of a self signed certificate.
-sha256Certificate data hash will be made by using SHA algorithm.
-noencPrivate key will not be encrypted. This is needed if we want to use our key automatically.
-days 365Our certificate will be valid from today ( 20.06.2026. ) till 20.06.2027.
-newkey rsa:2048We will create RSA asymmetric key with size of 2048 bits.
-keyout private.keyIn the current directory we will get a file with a private key.
-out certificate.crtIn the same directory we will get certificate file.

In terminal, we will now get a list of questions about certificate owner.
"RS" – 2 code abbreviation of a country name.
"Belgrade" – state or province.
"Belgrade" – city.
"Example Corp" – the name of the organization.
"Analytics Department" – department inside of the organization.
"Polychronis Hikari" – personal name. This is certificate for a person.
"hikari@gmail.com" – email address of that person.

Reading of Private Key and Certificate

We will use "x509" command to read our certificate:          openssl x509 -in certificate.crt -text -noout

We can notice that Issuer and Subject are the same. That is because this is self signed certificate. Algorithm used is SHA256 and RSA. The certificate is valid for 365 days from today.

For reading the private key, we use "pkey" command with similar options as for a certificate.
openssl pkey -in private.key -text -noout

The result will have a list of hexadecimal numbers. All of these numbers belong to RSA key. We can notice Modulus (N), Private (E) and Public (D) exponents, Prime 1 (P) and Prime 2 (Q). We used letters N, E, D, P, Q as variables for the explanation how RSA calculation works.

For reading of this key, we don't have to provide a password because the key is not encrypted.

CN Property Clarification

CN means "common name". CN is a text property. CN Property exists in the Subject and Issuer elements of the certificate.

Issuer:   CN = Let's Encrypt R12This is the name of a certification authority.
Subject: CN = example.com
               CN = Polychronius Hikari
               CN = My Root CA
Here we write domain name, or a person name, or the purpose of a key. The goal is to identify for what purpose will this key be used.

Long ago, CN for Subject was important because this was the place where we wrote a domain name. Internet browser would then verify this domain name with URL that client is trying to connect to. Long ago CN was one of the most important parts of a certificate.

The problem with CN is that was accepting only one domain. Users were not able to have many domains signed by the same certificate. Today the CN is not validated by modern internet browsers. Instead of CN we use SAN ( "Subject Alternative Name" ). SAN is part of extensions in a certificate. SAN has ability to accept several domain names.

Providing CN and SAN Value in "req -x509" Command

We can provide "C,ST,L,O,OU,CN,emailAddress" data with "-subj" option. We can provide SAN data with "-addtext" option.
openssl req -x509 -sha256 -noenc -days 365 -newkey rsa:2048 \
-subj "/C=RS/ST=Belgrade/L=Belgrade/O=Example Corp/OU=Analytics Department/CN=Polychronis Hikari/emailAddress=hikari@gmail.com" \
-addext "subjectAltName=email:hikari@gmail.com,DNS:polychronis.example.com,IP:127.0.0.1" \
-keyout private.key -out certificate.crt

For SAN data, we must define type of the protocol ( "email, DNS, IP" ). I will run the command above. This time we will not get prompts to provide "C,ST,L,O,OU,CN,emailAddress" data. We can read our certificate.

At the bottom of "Data:" section we have extensions. Here we can see the value of SAN extension.
SAN is not the only extensions that can be defined with "-addext" option. All extensions can be provided this way.

Root Domain, Wildcard Domain, Multidomain

-addext "subjectAltName=DNS:www.example.com"
                                                                     
This is valid for "https://www.example.com", but not for "https://example.com" and                                                                                                        "https://shop.example.com".

DNS:www.example.comRoot domains are only valid for the specific domain with precisely the same name.
DNS:www.example.com,DNS:maps.google.comMultidomain is set of several domains. We can use the certificate for all of them.
DNS:*.example.comThis is wild card domain. It is only useful for one level subdomain. Think about it as "<anything>.example.com". This wildcard domain will not work for "example.com" and "a.b.example.com", but it will work for "www.example.com" and "shop.example.com".

We can combine these domain names in different ways.DNS:www.example.com,DNS:maps.google.com,DNS:*.*.example.com

Encryption

I will create private key with encryption. I will use "-subj" option to avoid getting questions.
openssl req -x509 -sha256 -subj "/C=RS" -days 365 -newkey rsa:2048 -keyout private.key -out certificate.crt

This time I will get prompts for a password. Password must have at least 4 characters.
For reading this private key we must provide password.
openssl pkey -in private.key -text -noout

When a key is encrypted, the header of the key is changed. It says ENCRYPTED.We can decrypt private key like this:
openssl pkey -in private.key -out unencrypted.key

We can encrypt the key again.
openssl pkey -in unencrypted.key -aes256 -out private.key

Password

openssl pkey -in private.key -out unencrypted.key -passin pass:"pass123"
openssl pkey -in unencrypted.key -aes256 -out private.key -passout pass:"pass123"

                                                                                                                              
We can encrypt and decrypt the key again, but this time, we can provide a password inside of the OpenSSL command.

Important thing is that we must provide the source of a password. Source can be stdin, a file or a an environ.

echo "pass123" > pass.txt
export MYPASSWORD="pass123"
I will create a file with a password, and I will also create one environ with a password.

We can decrypt the key with the password from the file.
openssl pkey -in private.key -out unencrypted.key -passin file:"pass.txt"
We can encrypt it with the password from an environ.
openssl pkey -in unencrypted.key -aes256 -out private.key -passout env:MYPASSWORD

Self Signed Eliptic Key

The command that will create EC keys is similar. This time we have another option "-pkeyopt".
openssl req -x509 -sha256 -subj "/C=RS" -noenc -days 365 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout private.key -out certificate.crt

For EC keys we must choose a "curve". This is parameter that is deciding the strength of the key.ec_paramgen_curve:prime256v1           # most popular for web sites ec_paramgen_curve:secp384r1            # stronger, for governments and banks ec_paramgen_curve:secp521r1            # strongest, but rarely used
openssl ecparam -list_curvesWe can list all of the curves by using this command. There are dozens of these curves.

When we use "-pkeyopt", we choose a curve. Instead of that we can choose algorithm directly. Algorithm already has a curve specified. These are newer algorithms. For algorithms we are using option "-algorithm". These are two used the most.-algorithm X25519
                              
-algorithm ED25519
                              

EC keys are much smaller than RSA keys. On the image we can see the whole key. That is why EC is faster than RSA.

Exporting a Public Key

We can get a public key based on the private key.
openssl pkey -in private.key -pubout  

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE12P1PRoujnQCWgwCvPyN8q1CR/Pl
tCoegq6+OAQ6iqRe9R0SNtnml3FBPUijajZwLXv9IkGJIJ2BrvXkALBe/w==
-----END PUBLIC KEY-----
We can get public key from the certificate.
openssl x509 -in certificate.crt -pubkey -noout  

-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE12P1PRoujnQCWgwCvPyN8q1CR/Pl tCoegq6+OAQ6iqRe9R0SNtnml3FBPUijajZwLXv9IkGJIJ2BrvXkALBe/w==
-----END PUBLIC KEY-----

Linking Private Key and the Certificate

We can see above that exported public keys, from the private key and from the certificate, are the same. We can use that fact to detect linked private keys and certificates. Because public keys can be long, we will create digest from them, so we can easily compare those digests.

openssl pkey -in private.key -pubout | openssl sha256  

SHA2-256(stdin)= 0a44ba248fa6ca1ba6d392f93f00858d6abc84b4c8ffa59471d9ee8c003e63b7
openssl x509 -in certificate.crt -pubkey -noout | openssl sha256  

SHA2-256(stdin)= 0a44ba248fa6ca1ba6d392f93f00858d6abc84b4c8ffa59471d9ee8c003e63b7

Now we can eyeball that this private key and this certificate are linked together.

Exporting and Reading Public Key

This is how we can export public key to a file.
openssl pkey -in private.key -pubout -out public.pub
Pkey is a command for reading a private key. If we use option "-pubin", we can also use it to read public keys.
openssl pkey -in public.pub -noout -text -pubin

Leave a Comment

Your email address will not be published. Required fields are marked *