Encryption remains a cornerstone for safeguarding sensitive information. While commercial Certificate Authorities (CAs) provide trusted SSL certificates for public-facing services, a self-signed Certificate can be a practical and cost-effective solution for internal network communications.

Although modern browsers typically reject self-signed certificates due to trust issues, these certificates are valuable for encrypting internal traffic.

By creating your own self-signed certificate and using it to sign Certificate Signing Requests (CSRs), you can secure data transmission across your internal networks or implement mutual TLS (mTLS) for client and server authentication.

In this post, we explore the process of setting up a self-signed certificate and demonstrate how to sign CSRs, highlighting the benefits of this strategy for internal security resilience.


picture of a key

Create Private Key

The private key serves as the foundational element for creating a self-signed certificate because it is at the core of the cryptographic operations that underpin certificate signing and validation.

$ openssl genrsa -aes256 -out CA.key 4096

Note that we use OpenSSL to generate a secure 4096-bit asymmetric RSA private key and secure it with the symmetric AES algorithm. Other options for algorithms and key length can be found in the manpage of OpenSSL.

OpenSSL will ask for a passphrase. Protecting the private key is essential, as any compromise could allow malicious actors to issue fraudulent certificates, undermining trust and security within your internal environment.

Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

Create the Self-Signed Root Certificate

We can now proceed to create our self-signed root certificate using the private key.

$ openssl req -x509 -new -nodes -key CA.key -sha256 -days 1826 -out CA.crt

In this step, we use the sha256 hashing algorithms and set the certificate’s validity to 1826 days or roughly 5 years. As always, alternative options are available in the man page of OpenSSL.

You will be asked to enter the passphrase for the private key you selected, as well as to answer several questions.

Enter pass phrase for CA.key:
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]:DE
State or Province Name (full name) [Some-State]:Bavaria
Locality Name (eg, city) []:Munich
Organization Name (eg, company) [Internet Widgits Pty Ltd]:inversegravity    
Organizational Unit Name (eg, section) []:InfoSec
Common Name (e.g. server FQDN or YOUR name) []:inversegravity
Email Address []:[email protected]

While the responses to these questions are not particularly critical, they do appear when viewing the certificate, a task you will seldom need to do. For the Common Name, I recommend choosing something easily identifiable as your root certificate among other certificates.

With the self-signed Root Certificate, our internal “CA” is now operational.

Create a Certificate Signing Request (CSR)

Let’s generate our Certificate Signing Request (CSR) for our first certificate, which could be used to secure internal network traffic. This process mirrors what customers typically submit to a trusted Certificate Authority (CA) for signing.

$ openssl req -newkey rsa:2048 -keyout CSR.key -out CSR.csr

Unlike with our root certificate, where the key was generated separately, we create the private key alongside the CSR and use the RSA algorithm with a shorter key length of 2048 bits.

We also employ the -nodes option to leave the private key unencrypted, avoiding the need to enter a password when restarting the service utilizing the certificate.

Lastly, we omit the x509 argument to signal to OpenSSL that we are creating a CSR instead of a self-signed certificate.

..+................+............+..+.......+++++++++++++++++++++++++++++++++......
+++..........+++++++++++++++++++++++++++++++++++++++........+++++++++++++++++++...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++......+++++++++..........+


-----
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]:DE
State or Province Name (full name) [Some-State]:Bavaria
Locality Name (eg, city) []:Munich
Organization Name (eg, company) [Internet Widgits Pty Ltd]:inversegravity
Organizational Unit Name (eg, section) []:InfoSec
Common Name (e.g. server FQDN or YOUR name) []:nas.internal.inversegravity.net
Email Address []:[email protected]

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

The dots (.) and plus signs (+) you see provide a visual indication that the process of generating randomness required for key creation is underway, ensuring that the key is as secure as possible.

The password from the ‘extra’ attributes is not used to encrypt the CSR. It’s only used by some trusted CAs for certificate revocation. The optional company name can be omitted as well for our use-case.

Sign the CSR

Now it’s time to sign the CSR with our self-signed root certificate. We essentially act as your own CA in this case.

$ openssl x509 -req -days 365 -in CSRcsr -CA CA.crt -CAkey CA.key -out CSR.crt 
-set_serial 01 -sha256
Certificate request self-signature ok
subject=C = DE, ST = Bavaria, L = Munich, O = inversegravity, OU = security, 
CN = nas.internal.inversegravity.net, emailAddress = [email protected]
Enter pass phrase for CA.key:

You have to enter the password of the private key of the self-signed root certificate to sign the CSR.

Certificate Usage

Having generated a certificate, we can leverage it in various software development scenarios and internal network applications. However, it’s important to remember that web browsers do not inherently trust this certificate, as they typically require validation from a trusted Certificate Authority (CA) to establish authenticity.

Here are a few practical use cases where your certificate can be applied:

  • VPN Authentication: Certificates can be used to authenticate clients and servers within virtual private networks (VPNs). This ensures that only authorized users and devices can access the network, enhancing security and privacy.

  • Mutual Transport Layer Security (mTLS): In mTLS, both the client and server authenticate each other using certificates. This bidirectional authentication process adds an extra layer of security, ensuring that both parties are verified before communication is established.

  • Transport Layer Security (TLS): TLS is used to encrypt data transmitted over networks, securing communication between clients and servers. By using your certificate, you can facilitate encrypted connections within internal applications or systems, protecting sensitive data from interception and tampering.

Certificate Confusion

In this post we started by creating a self-signed root certificate, which, while not inherently trusted on the open internet, can serve as a trusted entity within our internal environments.

By using this root certificate, we’ve signed a Certificate Signing Request (CSR) to generate a “service” certificate. This certificate can be effectively used to secure an internal web server or protect our internal network, improving our security posture.

Although these service certificates are not automatically trusted by standard web browsers, they can be manually added for our internal services, ensuring smooth operations and heightened security within our controlled environments.

Utilizing self-signed certificates provides flexibility and control, allowing you to manage secure communications without the need for third-party Certificate Authorities (CAs).

                                +------------------+
                                | Root Certificate |
                                |    Self-Signed   |
                                +------------------+
                                          |
                                +---------+--------+
                                |                  |
                         +-------------+    +-------------+
                         | Certificate |    | Certificate |
                         +-------------+    +-------------+

Why Try Self-Signed Certificates?

  • Cost-Effective Security: You can enhance security without incurring the cost of purchasing certificates from external CAs, making it an economical choice for development and internal applications.

  • Learning Experience: Implementing self-signed certificates is a valuable exercise in understanding cryptographic concepts, certificate management, and network security principles.

  • Tailored Security: You can design security measures specifically tailored to your organization’s internal needs, ensuring that critical data and communications are protected.

I encourage everyone to explore and utilize self-signed certificates within your development and internal network environments. By doing so, you’ll gain practical insights into security management and discover how to effectively safeguard your systems and data.