Generate duplicate certificates OpenSSL CA [Same CN]


Written by - Deepak Prasad

 

Why we need to generate duplicate certificates with OpenSSL CA?

This use case is mostly valid for lab environments or when we are using self signed CA with 1000s or servers which gets re-deployed very often. In such case we sometimes tend to generate duplicate certificates which are used for internal communication in private network. Although such exercise should not be performed when using external communication in public network.

Just to be clear, here we we use the term 'duplicate certificates' we mean 'certificates with same Common Name' as Common Name is the most important field in a certificate which is used for authentication or authorization in any communication over SSL/TLS.

Normally we either use openssl ca or openssl x509 to sign the certificates. Now both of these commands sign and generate a certificate in different ways which we have covered in detail at openssl ca vs openssl x509 comparison [With Examples]

We will cover different examples using both the commands to generate duplicate certificates.

 

Setup Lab Environment

We have already installed openssl command and prepared our RootCA which we will use in this article to sign the certificates. I will just brief out the steps I have used for reference:

## navigate inside your tls path
cd /root/tls

## generate rootca private key
openssl genrsa  -out private/cakey.pem 4096

## generate rootCA certificate
openssl req -new -x509 -days 3650  -config openssl.cnf  -key private/cakey.pem -out certs/cacert.pem

## Verify the rootCA certificate content and X.509 extensions
openssl x509 -noout -text -in certs/cacert.pem

You can collect my sample openssl.cnf from a different article.

 

Method-1: Generate duplicate certificates using openssl x509 command

The openssl x509 command doesn't maintain any database for all the certificates which is signed using the CA certificate. The command does maintain a serial number database but that doesn't contain any details about the Certificate Signing Request so it is easier to create duplicate certificates here.

 

Generate private key

First we would need a private key for our certificate to generate the CSR

# openssl genrsa -out server.key.pem 4096

Sample Output:
Generate duplicate certificates OpenSSL CA [Same CN]

 

Generate Certificate Signing Request (CSR)

Next we generate the CSR required to sign the certificate. Here our Common Name would be server-1.example.com:

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

Sample Output:
Generate duplicate certificates OpenSSL CA [Same CN]

 

Sign and generate certificate

Next we will generate our certificate using the CSR and RootCA certificate:

# openssl x509 -req -in server.csr -CA /root/tls/certs/cacert.pem -CAkey /root/tls/private/cakey.pem -out server-1.cert.pem -CAcreateserial -days 365 -sha256                                                                             
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = server-1.example.com
Getting CA Private Key

So, we have successfully created our certificate:

# ls -l
total 12
-rw-r--r-- 1 root root 1952 Sep  5 11:03 server-1.cert.pem
-rw-r--r-- 1 root root 1724 Sep  5 11:02 server.csr
-rw------- 1 root root 3243 Sep  5 11:01 server.key.pem

 

Generate duplicate certificate using same CSR

Now let's try to generate another certificate using the same CSR file (having same Common Name)

# openssl x509 -req -in server.csr -CA /root/tls/certs/cacert.pem -CAkey /root/tls/private/cakey.pem -out server-2.cert.pem -CAcreateserial -days 365 -sha256
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = server-1.example.com
Getting CA Private Key

List the certificate:

# ls -l
total 16
-rw-r--r-- 1 root root 1952 Sep  5 11:03 server-1.cert.pem
-rw-r--r-- 1 root root 1952 Sep  5 15:51 server-2.cert.pem
-rw-r--r-- 1 root root 1724 Sep  5 11:02 server.csr
-rw------- 1 root root 3243 Sep  5 11:01 server.key.pem

As you can see, we have two certificates using the same Common Name.

 

Verify duplicate certificates

Both the certificates will have different serial number:

# openssl x509 -in server-1.cert.pem -noout -serial
serial=33BFBE13ED27ED780DBDA412F152D21E0A4C367D

# openssl x509 -in server-2.cert.pem -noout -serial
serial=33BFBE13ED27ED780DBDA412F152D21E0A4C367E

But both of them will have the same Subject field:

# openssl x509 -noout -text -in server-1.cert.pem | grep -E 'Issuer|Subject:'
        Issuer: C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = rootca.com
        Subject: C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = server-1.example.com

# openssl x509 -noout -text -in server-2.cert.pem | grep -E 'Issuer|Subject:'
        Issuer: C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = rootca.com
        Subject: C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = server-1.example.com

So with openssl x509 command we can generate n number of duplicate certificates without any issues as it doesn't maintain any database apart from serial number.

 

Method-2: Generate duplicate certificates using openssl ca command

In this section we will cover the same steps as above but we will generate and sign the certificate using openssl ca command.

 

Generate private key

Let's generate another set of private keys for this section:

# openssl genrsa -out server-2.key.pem 4096

Sample Output:
Generate duplicate certificates OpenSSL CA [Same CN]

 

Generate Certificate Signing Request

Next we need a Certificate Signing Request. Here we will use Common Name as server-2.example.com:

# openssl req -new -key server-2.key.pem -out server-2.csr

Sample Output:
Generate duplicate certificates OpenSSL CA [Same CN]

 

Add X.509 Extensions (Optional)

This step is not relevant for this article but as a general practice I will just add required X.509 extensions to our certificate. Although this wouldn't impact our outcome in the next steps.

# cat ext_template.cnf
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth

 

Generate and sign certificate

Next we will sign and generate our certificate using RootCA as created in the Lab Environment section:

# openssl ca -config /root/tls/openssl.cnf -notext -batch -in server-2.csr -out server-2.crt -extfile ext_template.cnf
Using configuration from /root/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 3 (0x3)
        Validity
            Not Before: Sep  5 04:54:24 2021 GMT
            Not After : Sep  5 04:54:24 2022 GMT
        Subject:
            countryName               = IN
            stateOrProvinceName       = Karnataka
            organizationName          = golinuxcloud
            organizationalUnitName    = admin
            commonName                = server-1.example.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Client, S/MIME
            Netscape Comment:
                OpenSSL Generated Client Certificate
            X509v3 Subject Key Identifier:
                DC:9F:78:27:9F:7F:DD:25:96:70:74:9B:EC:07:C5:DB:DE:AD:8D:DB
            X509v3 Authority Key Identifier:
                keyid:E4:A4:AB:AA:DC:F5:FC:58:CD:24:DB:24:28:F8:8D:77:A9:EE:B4:3E

            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
Certificate is to be certified until Sep  5 04:54:24 2022 GMT (365 days)

Write out database with 1 new entries
Data Base Updated

Verify the index.txt database of the rootca:

# cat /root/tls/index.txt
R       220905044447Z   210905045305Z   01      unknown /C=IN/ST=Karnataka/O=golinuxcloud/OU=admin/CN=server-1.example.com
V       220905044529Z           02      unknown /C=IN/ST=karnataka/O=golinuxcloud/OU=admin/CN=server-2.example.com
V       220905045424Z           03      unknown /C=IN/ST=Karnataka/O=golinuxcloud/OU=admin/CN=server-1.example.com

So with 02 serial, we have a new entry in our RootCA database for server-2.example.com.

 

Generate duplicate certificate using the same CSR

Let us try to use the same CSR from this section i.e. server-2.csr to generate another certificate:

# openssl ca -config /root/tls/openssl.cnf -days 10 -notext -batch -in server-2.csr -out server-4.crt -extfile ext_template.cnf
Using configuration from /root/tls/openssl.cnf
Check that the request matches the signature
Signature ok
ERROR:There is already a certificate for /C=IN/ST=karnataka/O=golinuxcloud/OU=admin/CN=server-2.example.com
The matching entry has the following details
Type          :Valid
Expires on    :220905044529Z
Serial Number :02
File name     :unknown
Subject Name  :/C=IN/ST=karnataka/O=golinuxcloud/OU=admin/CN=server-2.example.com

As expected, the certificate generation has failed because we already have an entry in the index.txt for server-2.example.com Common Name and unless we revoke this certificate, the same can not be re-signed.

 

How do I fix this and generate duplicate certificates with OpenSSL?

As soon as the CA signs a certificate, it creates a new file index.txt.attr in the same location where index.txt resides. For us, since we are using /root/tls as our base directory to store CA certificates and files so we can look into the same path:

]# cat /root/tls/index.txt.attr
unique_subject = yes

Change the value of unique_subject to no so that openssl will not check for Subject name while signing the certificates

]# cat /root/tls/index.txt.attr
unique_subject = no

Now, let us try to sign the certificate again:

# openssl ca -config /root/tls/openssl.cnf -days 10 -notext -batch -in server-2.csr -out server-4.crt -extfile ext_template.cnf
Using configuration from /root/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 5 (0x5)
        Validity
            Not Before: Sep  5 11:03:26 2021 GMT
            Not After : Sep 15 11:03:26 2021 GMT
        Subject:
            countryName               = IN
            stateOrProvinceName       = karnataka
            organizationName          = golinuxcloud
            organizationalUnitName    = admin
            commonName                = server-2.example.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Client, S/MIME
            Netscape Comment:
                OpenSSL Generated Client Certificate
            X509v3 Subject Key Identifier:
                8E:E1:06:4C:21:CA:C6:2E:8A:1D:D2:20:10:40:43:3D:51:73:C9:14
            X509v3 Authority Key Identifier:
                keyid:E4:A4:AB:AA:DC:F5:FC:58:CD:24:DB:24:28:F8:8D:77:A9:EE:B4:3E

            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
Certificate is to be certified until Sep 15 11:03:26 2021 GMT (10 days)

Write out database with 1 new entries
Data Base Updated

So, this time we were able to generate the certificate with the same Common Name. verify the ca's database:

# cat /root/tls/index.txt
R       220905044447Z   210905045305Z   01      unknown /C=IN/ST=Karnataka/O=golinuxcloud/OU=admin/CN=server-1.example.com
V       220905044529Z           02      unknown /C=IN/ST=karnataka/O=golinuxcloud/OU=admin/CN=server-2.example.com
V       220905045424Z           03      unknown /C=IN/ST=Karnataka/O=golinuxcloud/OU=admin/CN=server-1.example.com
V       100111044010Z           04      unknown /C=IN/ST=Karnataka/O=golinuxcloud/OU=admin/CN=server-3.example.com
V       210915110326Z           05      unknown /C=IN/ST=karnataka/O=golinuxcloud/OU=admin/CN=server-2.example.com

Here ignore the server-3.example.com certificate which I had created as part of different exercise. You can notice the serial 02 and 05 content and they both have the same Subject Name so we were able to generate duplicate certificates here.

 

Summary

In this tutorial we covered the steps to generate duplicate certificates using openssl command. As explained we normally don't create multiple certificates using the same Subject Name in production environment and specially for external communication. if any certificate is lost, compromised or expired, in such case one should first revoke the certificate in question and then generate a new one to have a secure environment.

Although for lab use cases we may need these hacks to generate multiple certificates for containers or nodes which are frequently re-deployed.

 

References

Generating duplicate certificates with OpenSSL CA

 

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can reach out to him on his LinkedIn profile or join on Facebook page.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment

X