openssl PKI – generate certificates with intermediate cA

Introduction

In this article, we will create a PKI that will use intermediate certificate authorities (CA). It means that the root CA will generate only intermediate certificate authorities and therefore, the root CA won’t issue any server or user certificate.
We will create a Server intermediate CA that will issue SSL server certificates and a User intermediate CA that will issue SSL client certificates (to authenticate users).

The required steps are:

– Create the root CA

– Create the Server intermediate CA (signed by the root CA)

– Create the User intermediate CA (signed by the root CA)

– Issue a SSL server certificate (signed by the Server intermediate CA)

– Issue a SSL user certificate (signed by the User intermediate CA)

Prerequiste: The PKI OpenSSL scripts must be installed – See the page which describes the setup.

Create the root certificate authority

The first thing to do is to create the root certificate authority (CA).

It is this authority that will sign the intermediate certificate authorities if you choose to make use of them or that will sign the users’ and servers’ certificates if you don’t want to use intermediate CA.

To create the Root CA, use the “issue-ca-rootca.sh” script:

$ issue-ca-rootca.sh
In progress …

Generating the RSA private and public key …
16384 semi-random bytes loaded
Generating RSA private key, 4096 bit long modulus
……………………………………………………..++
………………………………………………………………………………………………………………………………………………………………………………………………………………………………………++
unable to write ‘random state’
e is 65537 (0x10001)
Enter pass phrase for /app/PKI/database/private/ca.key: [Choose a pass phrase to protect the root CA private key]
Verifying – Enter pass phrase for /app/PKI/database/private/ca.key: [Enter the same pass phrase]

Setting ACL for the private Key …

Self signing the certificate …
Enter pass phrase for /app/PKI/database/private/ca.key: [Enter the pass phrase of the root CA private 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 ) [FR]: [Press Enter for default or type your own value]
State or Province Name * ( full name ) [France]: [Press Enter for default or type your own value]
Locality Name * ( eg, city ) [Paris]: [Press Enter for default or type your own value]
Organization Name * ( eg, company ) [BLP]: [Press Enter for default or type your own value]
Organizational Unit Name ( eg, section ) [Security Department]: [Press Enter for default or type your own value]
Common Name * ( eg, Root CA Name ) []: [Choose a name for your root Certificate Authority]
E-Mail Address [firstname.lastname@le-piolot.fr]: [Press Enter for default or type your own value]

Updating Trusted CA Chain …
Doing /app/PKI/database/CAchain
ca.pem => a4282202.0

Done. Certificate is available in file “/app/PKI/database/certs/ca.crt”, Private Key in file “/app/PKI/database/private/ca.key”.

As indicated by the script, the root CA certificate is located in “database/certs/ca.crt”.

Create the Server intermediate certificate authority

If you want to maker use of intermediate certificate authorities, I would suggest to use different certificate authority for servers’ certificates and for users’ certificates. In this section, we will create an intermediate CA (which will be signed by the root CA) that will be used to generate (sign) servers’ certificates.
To create the a server intermediate CA, use the “issue-ca-server-subca.sh” script:
$ issue-ca-server-subca.sh
In progress …

Generating the RSA private and public key …
16384 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
…………………………+++
…+++
unable to write ‘random state’
e is 65537 (0x10001)
Enter pass phrase for /app/PKI/database/private/Server_SubCA.key: [Choose a pass phrase to protect the Server CA private key]
Verifying – Enter pass phrase for /app/PKI/database/private/Server_SubCA.key: [Enter the same pass phrase]

Setting ACL for the private Key …

Generating the Certificate Signing Request …
Enter pass phrase for /app/PKI/database/private/Server_SubCA.key: [Enter the pass phrase of the Server CA private 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 ) [FR]: [Press Enter for default or type your own value]
State or Province Name * ( full name ) [France]: [Press Enter for default or type your own value]
Locality Name * ( eg, city ) [Paris]: [Press Enter for default or type your own value]
Organization Name ** ( eg, company ) [BLP]: [Press Enter for default or type your own value]
Organizational Unit Name ( eg, section ) [Security Department]: [Press Enter for default or type your own value]
Common Name * ( eg, Sub CA Name ) []: [Choose a name for your Server Certificate Authority]
E-Mail Address [firstname.lastname@le-piolot.fr]: [Press Enter for default or type your own value]

Generating the Server Intermediate CA Certificate signed by the Root CA …
Using configuration from /app/PKI/etc/ca-subca-cert.cnf
Enter pass phrase for /app/PKI/database/private/ca.key: [Enter the pass phrase of the root CA private key]
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName           :PRINTABLE:’FR’
stateOrProvinceName   :PRINTABLE:’France’
localityName          :PRINTABLE:’Paris’
organizationName      :PRINTABLE:’BLP’
organizationalUnitName:PRINTABLE:’Security Department’
commonName            :PRINTABLE:’BLP Server Intermediate CA’
emailAddress          :IA5STRING:’firstname.lastname@le-piolot.fr’
Certificate is to be certified until Jan 14 21:09:39 2030 GMT (5475 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
unable to write ‘random state’

Updating Trusted CA Chain …
Doing /app/PKI/database/CAchain
ca.pem => a4282202.0
Server_SubCA.pem => b41968af.0

Done. Certificate is available in file “/app/PKI/database/certs/Server_SubCA.crt”, Private Key in file “/app/PKI/database/private/Server_SubCA.key”.

As indicated by the script, the certificate of the server intermediate CA is located in “database/certs/Server_SubCA.crt”.

Create the User intermediate certificate authority

If you want to maker use of intermediate certificate authorities, I would suggest to use different certificate authority for servers’ certificates and for users’ certificates. In this section, we will create an intermediate CA (which will be signed by the root CA) that will be used to generate (sign) users’ certificates.
To create the a user intermediate CA, use the “issue-ca-user-subca.sh” script:

$ issue-ca-user-subca.sh
In progress …

Generating the RSA private and public key …
16384 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
…………………………………………………………………………………..+++
………………………………..+++
unable to write ‘random state’
e is 65537 (0x10001)
Enter pass phrase for /app/PKI/database/private/User_SubCA.key: [Choose a pass phrase to protect the User CA private key]
Verifying – Enter pass phrase for /app/PKI/database/private/User_SubCA.key: [Enter the same pass phrase]

Setting ACL for the private Key …

Generating the Certificate Signing Request …
Enter pass phrase for /app/PKI/database/private/User_SubCA.key: [Enter the pass phrase of the User CA private 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 ) [FR]: [Press Enter for default or type your own value]
State or Province Name * ( full name ) [France]: [Press Enter for default or type your own value]
Locality Name * ( eg, city ) [Paris]: [Press Enter for default or type your own value]
Organization Name ** ( eg, company ) [BLP]: [Press Enter for default or type your own value]
Organizational Unit Name ( eg, section ) [Security Department]: [Press Enter for default or type your own value]
Common Name * ( eg, Sub CA Name ) []: [Choose a name for your User Certificate Authority]
E-Mail Address [firstname.lastname@le-piolot.fr]: [Press Enter for default or type your own value]

Generating the User Intermediate CA Certificate signed by the Root CA …
Using configuration from /app/PKI/etc/ca-subca-cert.cnf
Enter pass phrase for /app/PKI/database/private/ca.key: [Enter the pass phrase of the root CA private key]
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName           :PRINTABLE:’FR’
stateOrProvinceName   :PRINTABLE:’France’
localityName          :PRINTABLE:’Paris’
organizationName      :PRINTABLE:’BLP’
organizationalUnitName:PRINTABLE:’Security Department’
commonName            :PRINTABLE:’BLP User Intermediate CA’
emailAddress          :IA5STRING:’firstname.lastname@le-piolot.fr’
Certificate is to be certified until Jan 14 21:38:54 2030 GMT (5475 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
unable to write ‘random state’

Updating Trusted CA Chain …
Doing /app/PKI/database/CAchain
ca.pem => a4282202.0
Server_SubCA.pem => b41968af.0
User_SubCA.pem => 58f1f360.0

Done. Certificate is available in file “/app/PKI/database/certs/User_SubCA.crt”, Private Key in file “/app/PKI/database/private/User_SubCA.key”.

As indicated by the script, the certificate of the user intermediate CA is located in “database/certs/User_SubCA.crt”.

Create a server certificate signed by the intermediate CA

Now that we have the server intermediate CA, we can use it to create a server certificate.

To create a server certificate, use the “issue-cert-server.sh” script with an argument which is the name of the files that will hold the private key and the associated certificate. Give a filename without extension (for instance, you can use the CN of the certificate as the argument).

$ issue-cert-server.sh [Common Name of the Server – for instance: ssi.le-piolot.fr]
In progress …

Generating the RSA private and public key …
16384 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
………………………………+++
….+++
unable to write ‘random state’
e is 65537 (0x10001)
Enter pass phrase for /app/PKI/database/private/ssi.le-piolot.fr.key: [Choose a pass phrase to protect the Server private key]
Verifying – Enter pass phrase for /app/PKI/database/private/ssi.le-piolot.fr.key: [Enter the same pass phrase]

Setting ACL for the private Key …

Generating the Certificate Request …
Enter pass phrase for /app/PKI/database/private/ssi.le-piolot.fr.key: [Enter the pass phrase of the Server private 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 ) [FR]: [Press Enter for default or type your own value]
State or Province Name ( full name ) [France]: [Press Enter for default or type your own value]
Locality Name ( eg, city ) [Paris]: [Press Enter for default or type your own value]
Organization Name * ( eg, company ) [BLP]: [Press Enter for default or type your own value]
Organizational Unit Name ( eg, section ) [Security Department]: [Press Enter for default or type your own value]
Common Name * ( eg, www.domain.com ) []: [Common Name of the Server – for instance: ssi.le-piolot.fr]
E-Mail Address [firstname.lastname@le-piolot.fr]: [Press Enter for default or type your own value]

Generating the Certificate signed by the Server Intermediate CA …
Using configuration from /app/PKI/etc/ca-server-cert.cnf
Enter pass phrase for /app/PKI/database/private/Server_SubCA.key: [Enter the pass phrase of the Server CA private key]
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName           :PRINTABLE:’FR’
stateOrProvinceName   :PRINTABLE:’France’
localityName          :PRINTABLE:’Paris’
organizationName      :PRINTABLE:’BLP’
organizationalUnitName:PRINTABLE:’Security Department’
commonName            :PRINTABLE:’ssi.le-piolot.fr’
emailAddress          :IA5STRING:’firstname.lastname@le-piolot.fr’
Certificate is to be certified until Jan 15 21:47:39 2025 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
unable to write ‘random state’

Done. Certificate is available in file “/app/PKI/database/certs/ssi.le-piolot.fr.crt”, Private Key in file “/app/PKI/database/private/ssi.le-piolot.fr.key”.

As indicated by the script, the certificate of the server is located in “database/certs” and the associated private key is in “database/private”. You then have to deploy these files to the application (Apache httpd, …).

I also created a script to generate a PKCS#12 file containing the certificate, the private key and the certificate chain. The PKCS#12 format is usefull to import the certificates in Windows or in Java Keystores.

Create a user (client) certificate signed by the intermediate CA

Now that we have the user intermediate CA, we can use it to create a user (client) certificate.

To create a user certificate, use the “issue-cert-user.sh” script with an argument which is the name of the files that will hold the private key and the associated certificate. Give a filename without extension (for instance, you can use the CN of the certificate as the argument without spaces).
$ issue-cert-user.sh [Common Name of the User – for instance: bertrand]
In progress …

Generating the RSA private and public key …
16384 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
..+++
…………………………………………+++
unable to write ‘random state’
e is 65537 (0x10001)
Enter pass phrase for /app/PKI/database/private/bertrand.key: [Choose a pass phrase to protect the User private key]
Verifying – Enter pass phrase for /app/PKI/database/private/bertrand.key: [Enter the same pass phrase]

Setting ACL for the private Key …

Generating the Certificate Request …
Enter pass phrase for /app/PKI/database/private/bertrand.key: [Enter the pass phrase of the User private 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 ) [FR]: [Press Enter for default or type your own value]
State or Province Name ( full name ) [France]: [Press Enter for default or type your own value]
Locality Name ( eg, city ) [Paris]: [Press Enter for default or type your own value]
Organization Name ( eg, company ) [BLP]: [Press Enter for default or type your own value]
Organizational Unit Name ( eg, section ) [Security Department]: [Press Enter for default or type your own value]
Common Name * ( eg, your name ) []:[Common Name of the Server – for instance: Bertrand]
E-Mail Address * [firstname.lastname@le-piolot.fr]: [Press Enter for default or type your own value]

Generating the User Certificate signed by the User Intermediate CA …
Using configuration from /app/PKI/etc/ca-user-cert.cnf
Enter pass phrase for /app/PKI/database/private/User_SubCA.key: [Enter the pass phrase of the User CA private key]
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName           :PRINTABLE:’FR’
stateOrProvinceName   :PRINTABLE:’France’
localityName          :PRINTABLE:’Paris’
organizationName      :PRINTABLE:’BLP’
organizationalUnitName:PRINTABLE:’Security Department’
commonName            :PRINTABLE:’Bertrand’
emailAddress          :IA5STRING:’firstname.lastname@le-piolot.fr’
Certificate is to be certified until Jan 17 21:56:46 2020 GMT (1825 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
unable to write ‘random state’

Done. Certificate is available in file “/app/PKI/database/certs/bertrand.crt”, Private Key in file “/app/PKI/database/private/bertrand.key”.

As indicated by the script, the certificate of the user is located in “database/certs” and the associated private key is in “database/private”. You then have to deploy these files to the application (Apache httpd, …).

I also created a script to generate a PKCS#12 file containing the certificate, the private key and the certificate chain. The PKCS#12 format is usefull to import the certificates in Windows or in Java Keystores.

openssl PKI – generate certificates with intermediate cA

Leave a Reply

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