ar_doc_18 openssl_ECC_enc_dec_signature - JohnHau/mis GitHub Wiki

openssl ca vs openssl x509 comparison [With Examples] Table of Contents openssl ca vs openssl x509 comparison Generate RootCA Certificate Create directory structure Sample openssl.cnf Generate private key Generate RootCA certificate Verify RootCA certificate X509 Extensions Generate and sign certificate using openssl x509 command Generate private key Generate Certificate Signing request Generate and sign certificate using openssl x509 command What would happen if I sign the same certificate again? Generate and sign certificate using openssl ca command Generate private key Generate CSR Generate and sign server certificate What would happen if I sign the same certificate again? Summary Further Reading openssl ca vs openssl x509 comparison openssl is a single command which supports different set of operations when used with ca or x509 argument. Both the commands are used in a way to sign certificate requests openssl x509 is considered as a multi-purpose certificate utility because it can do much more than signing certificate requests, such as view certificate content, convert certificate formats etc. openssl ca doesn't provide these features. openssl ca and openssl x509, both can be used to sign certificate requests. But openssl ca command is used when you want to maintain a database of the list of certificates which are signed and revoked. openssl x509 maintains no such database. You can sign the same certificate (i.e. with same Common Name) n number of times with openssl x509 command but openssl ca command will not allow you to sign the same certificate more than 1 time as it maintains a database of the signed certificate. In such scenarios you must first revoke the existing certificate and then you may continue to get is signed again using openssl ca command

Let us understand the comparison with some examples

Generate RootCA Certificate We would need a rootCA certificate to sign the certificates so first let use create one rootCA certificate.

Create directory structure We will create our directory structure to keep all our rootCA related certificates.

Here index.txt is used to keep a track of all the certificates which will be signed by our RootCA certificate. The serial and crlnumber file will be used to keep the serial number for every certificate which is either signed or revoked respectively.

[root@controller tls]# mkdir /root/tls/{certs,private,crl} [root@controller tls]# touch serial crlnumber index.txt [root@controller tls]# echo 01 > serial [root@controller tls]# echo 1000 > crlnumber You can add any number into the serial and crlnumber file to start with, now going forward every time we sign or revoke a certificate, respective file's entry will be incremented by 1.

List the available files under our /root/tls directory:

[root@controller tls]# ls -l total 28 drwxr-xr-x 2 root root 4096 Aug 28 17:23 certs drwxr-xr-x 2 root root 4096 Aug 28 17:23 crl -rw-r--r-- 1 root root 5 Aug 28 17:25 crlnumber -rw-r--r-- 1 root root 0 Aug 28 17:25 index.txt drwxr-xr-x 2 root root 4096 Aug 28 17:23 private -rw-r--r-- 1 root root 3 Aug 28 17:25 serial

Sample openssl.cnf Below is our sample openssl.cnf file which we have created under /root/tls directory:

[root@controller tls]# cat openssl.cnf Sample Output:

[ ca ] default_ca = CA_default # The default ca section

[ CA_default ] dir = /root/tls # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/certs # default place for new certs. certificate = $dir/certs/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem # The private key x509_extensions = v3_ca # The extensions to add to the cert default_days = 3650 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = sha512 # use SHA-256 by default preserve = no # keep passed DN ordering policy = policy_match

This section is used to generate CSR for RootCA

[ policy_match ] countryName = match ## Must match RootCA CSR and any certificate this RootCA signs stateOrProvinceName = match ## Must match RootCA CSR and any certificate this RootCA signs organizationName = match ## Must match RootCA CSR and any certificate this RootCA signs organizationalUnitName = optional commonName = supplied emailAddress = optional

[ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional

[ req ] default_bits = 4096 default_md = sha512 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extensions to add to the self signed cert string_mask = utf8only

[ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = IN countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some-State localityName = Locality Name (eg, city) localityName_default = BANGALORE 0.organizationName = Organization Name (eg, company) 0.organizationName_default = GoLinuxCloud organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, your name or your servers hostname) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64

[ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name

Extensions used for RootCA certificate

[ v3_ca ]
subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical,CA:true nsComment = "OpenSSL Generated Certificate"

[ v3_req ]

Extensions to add to a certificate request

basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment

Generate private key Generate a private key for the rootCA certificate:

[root@controller tls]# openssl genrsa -out private/cakey.pem 4096 Generating RSA private key, 4096 bit long modulus (2 primes) ......................................................................++++ ...............++++ e is 65537 (0x010001)

Generate RootCA certificate IMPORTANT NOTE: Many people miss most important points when they are creating a CSR. If you are not sure about what should be added for individual fields then I would recommend to read this article before you generate CSR: Things to consider when creating CSR with OpenSSL

Next we will create our RootCA certificate using openssl x509 command. We have explicitly defined v3_ca extension to be used for the rootCA certificate. We have already defined v3_ca field with the x509 extensions required for RootCA.

[root@controller tls]# openssl req -new -x509 -days 3650 -config openssl.cnf -extensions v3_ca -key private/cakey.pem -out certs/cacert.pem 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) [IN]: State or Province Name (full name) [Some-State]:Karnataka Locality Name (eg, city) [BANGALORE]: Organization Name (eg, company) [GoLinuxCloud]: Organizational Unit Name (eg, section) []:RootCA Common Name (eg, your name or your server's hostname) []:rootca.com Email Address []:

Following are the list of files available under /root/tls at this stage:

[root@controller tls]# tree .

image

Verify RootCA certificate X509 Extensions Verify the x509 extensions from the rootca certificate:

[root@controller tls]# openssl x509 -noout -text -in certs/cacert.pem | grep -A10 "X509v3 extensions:" X509v3 extensions: X509v3 Subject Key Identifier: 61:01:DC:7C:C2:5D:41:BF:2B:BE:B2:D8:33:69:23:7A:15:C2:B1:A5 X509v3 Authority Key Identifier: keyid:61:01:DC:7C:C2:5D:41:BF:2B:BE:B2:D8:33:69:23:7A:15:C2:B1:A5

        X509v3 Basic Constraints: critical
            CA:TRUE
        Netscape Comment:
            OpenSSL Generated Certificate
Signature Algorithm: sha512WithRSAEncryption

Generate and sign certificate using openssl x509 command In this section we will generate and sign certificates using openssl x509 command. I will use /certs_x509 directory to store the certificates we create in this section.

Generate private key First let us generate the private key for the server certificate:

[root@controller certs_x509]# openssl genrsa -out server.key.pem 4096 Generating RSA private key, 4096 bit long modulus (2 primes) ....................................................................................................................................++++ ................................................................................................................................++++ e is 65537 (0x010001)

Generate Certificate Signing request Next we will generate CSR for the server certificate:

[root@controller certs_x509]# openssl req -new -key server.key.pem -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) [XX]:IN State or Province Name (full name) []:KARNATAKA Locality Name (eg, city) [Default City]:BENGALURU Organization Name (eg, company) [Default Company Ltd]:GOLINUXCLOUD Organizational Unit Name (eg, section) []:ADMIN Common Name (eg, your name or your server's hostname) []:controller.example.com Email Address []:[email protected]

Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: NOTE: I have provided different values for State name, locality name and organization name compared to the CSR I used for RootCA certificate. Now this may not be important in this section but this will be important factor when we use openssl ca command to generate and sign certificates

Generate and sign certificate using openssl x509 command Next we will use openssl x509 command to sign and generate our server certificate:

[root@controller certs_x509]# openssl x509 -req -in server.csr -CA /root/tls/certs/cacert.pem -CAkey /root/tls/private/cakey.pem -out server.cert.pem -CAcreateserial -CAserial serial -days 365 -sha256 Signature ok subject=C = IN, ST = KARNATAKA, L = BENGALURU, O = GOLINUXCLOUD, OU = ADMIN, CN = controller.example.com, emailAddress = [email protected] Getting CA Private Key

Here,

-CA specifies the CA certificate to be used for signing. -CAkey sets the CA private key to sign a certificate with. -out specifies the output filename to write to or standard output by default. -CAcreateserial with this option the CA serial number file is created if it does not exist. -CAserial serial sets the CA serial number file to use. -days specifies the number of days to make a certificate valid for. Verify if the certificate and the serial file have been created in the current working directory:

[root@controller certs_x509]# ls -l total 16 -rw-r--r-- 1 root root 41 Aug 28 17:51 serial -rw-r--r-- 1 root root 2009 Aug 28 17:51 server.cert.pem -rw-r--r-- 1 root root 1781 Aug 28 17:45 server.csr -rw------- 1 root root 3243 Aug 28 17:44 server.key.pem Check the content of the serial file:

[root@controller certs_x509]# cat serial 7E107B565C51DFD2F24B279953215D2AAF689F16

You can also check the serial of the certificate using following command:

[root@controller certs_x509]# openssl x509 -in server.cert.pem -noout -serial serial=7E107B565C51DFD2F24B279953215D2AAF689F16

What would happen if I sign the same certificate again? Let us try to sign the same certificate again using the rootCA:

[root@controller certs_x509]# openssl x509 -req -in server.csr -CA /root/tls/certs/cacert.pem -CAkey /root/tls/private/cakey.pem -out server.cert.pem -CAcreateserial -CAserial serial -days 365 -sha256 Signature ok subject=C = IN, ST = KARNATAKA, L = BENGALURU, O = GOLINUXCLOUD, OU = ADMIN, CN = controller.example.com, emailAddress = [email protected] Getting CA Private Key

As you case see, the openssl x509 has again signed the certificate without any issues. It has also updated the serial number of the certificate:

[root@controller certs_x509]# cat serial 7E107B565C51DFD2F24B279953215D2AAF689F17

[root@controller certs_x509]# openssl x509 -in server.cert.pem -noout -serial serial=7E107B565C51DFD2F24B279953215D2AAF689F17 This is because openssl x509 does not maintain a database of the certificate it signs using the root CA certificate. So it can sign the same certificate multiple times without the need of revocation.

Generate and sign certificate using openssl ca command Now in this section we will generate and sign certificates using openssl ca command. This should give you a basic idea of the difference between both the command.

I will store all the certificates generated at this section under /certs_ca directory.

Generate private key First of all let us generate a private key for the server certificate:

[root@controller certs_ca]# openssl genrsa -out server.key.pem 4096 Generating RSA private key, 4096 bit long modulus (2 primes) .......................................................................................++++ .....................++++ e is 65537 (0x010001)

Generate CSR Next we will generate the Certificate Signing Request. Here also we will intentionally provide a different value for respective fields compared to what we provided with RootCA CSR:

[root@controller certs_ca]# openssl req -new -key server.key.pem -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) [XX]:IN State or Province Name (full name) []:Karnataka Locality Name (eg, city) [Default City]:Bengaluru Organization Name (eg, company) [Default Company Ltd]:Some Company Organizational Unit Name (eg, section) []:Admin Common Name (eg, your name or your server's hostname) []:controller.example.com Email Address []:

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

Generate and sign server certificate Now let us use openssl ca to generate and sign the certificate. With openssl we must provide a valid openssl.cnf file which will contain all the details such as location of certificates, serial and index.txt files etc. We will use the openssl.cnf which we had created for rootCA certificate.

[root@controller certs_ca]# openssl ca -config /root/tls/openssl.cnf -days 2650 -notext -batch -in server.csr -out server.crt Using configuration from /root/tls/openssl.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'IN' stateOrProvinceName :ASN.1 12:'Karnataka' localityName :ASN.1 12:'Bengaluru' organizationName :ASN.1 12:'Some Company' organizationalUnitName:ASN.1 12:'Admin' commonName :ASN.1 12:'controller.example.com' The organizationName field is different between CA certificate (GoLinuxCloud) and the request (Some Company) As expected the openssl ca command failed to sign the certificate because the State Name is different in the rootCA CSR compared to the CSR which we generated for our server certificate.

This is another difference between openssl ca and openssl x509 commands. The openssl x509 command doesn't aggressively match the Subject details between Issuer and the consumer while openssl ca command follows the policy section of openssl.cnf to match these values.

I had already explained this part in Things to consider when creating CSR with OpenSSL

You can check the policy section used for RootCA in our openssl.cnf:

[ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional So the rootCA expects that countryName, stateOrProvinceName and organizationName is exactly the same between RootCA and certificate which wants to get signed from this rootCA.

You may also modify the policy and generate your RootCA accordingly.

But for now, we will re-generate our CSR for the server certificate with the same values as used for RootCA:

[root@controller certs_ca]# openssl req -new -key server.key.pem -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) [XX]:IN State or Province Name (full name) []:Karnataka Locality Name (eg, city) [Default City]:BANGALORE Organization Name (eg, company) [Default Company Ltd]:GoLinuxCloud Organizational Unit Name (eg, section) []:Dev Common Name (eg, your name or your server's hostname) []:controller.example.com Email Address []:

Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Next re-attempt to sign and generate a server certificate using openssl ca command:

[root@controller certs_ca]# openssl ca -config /root/tls/openssl.cnf -days 2650 -notext -batch -in server.csr -out server.crt Using configuration from /root/tls/openssl.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'IN' stateOrProvinceName :ASN.1 12:'Karnataka' localityName :ASN.1 12:'BANGALORE' organizationName :ASN.1 12:'GoLinuxCloud' organizationalUnitName:ASN.1 12:'Dev' commonName :ASN.1 12:'controller.example.com' Certificate is to be certified until Nov 29 13:15:29 2028 GMT (2650 days)

Write out database with 1 new entries Data Base Updated

We have successfully signed and generated a server certificate.

Verify the index.txt and serial file content inside /root/tls:

[root@controller certs_ca]# cat /root/tls/index.txt V 281129131529Z 01 unknown /C=IN/ST=Karnataka/O=GoLinuxCloud/OU=Dev/CN=controller.example.com

[root@controller certs_ca]# openssl x509 -in server.crt -noout -serial serial=01

[root@controller certs_ca]# cat /root/tls/serial 02 As you can see, serial=01 is assigned to the certificate which we just created and the same has been updated in /root/tls/index.txt file. Since 01 serial number is assigned to a certificate so the serial number has automatically been incremented to 02.

This proves what I mentioned earlier, openssl ca command maintains a database of all the certificates signed.

What would happen if I sign the same certificate again? But let us try to re-sign the same certificate again. If you remember this had worked with openssl x509 command in the previous section:

[root@controller certs_ca]# openssl ca -config /root/tls/openssl.cnf -days 2650 -notext -batch -in server.csr -out server.crt Using configuration from /root/tls/openssl.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'IN' stateOrProvinceName :ASN.1 12:'Karnataka' localityName :ASN.1 12:'BANGALORE' organizationName :ASN.1 12:'GoLinuxCloud' organizationalUnitName:ASN.1 12:'Dev' commonName :ASN.1 12:'controller.example.com' ERROR:There is already a certificate for /C=IN/ST=Karnataka/O=GoLinuxCloud/OU=Dev/CN=controller.example.com The matching entry has the following details Type :Valid Expires on :281129131529Z Serial Number :01 File name :unknown Subject Name :/C=IN/ST=Karnataka/O=GoLinuxCloud/OU=Dev/CN=controller.example.com So unlike openssl x509 command, the openssl ca command will not allow you to sign the same certificate again as the database already contains an entry for this Common Name.

To sign the same certificate again, you must first revoke this certificate and then you can sign it again.

Summary In this article I have explained and covered the similarities and difference between openssl ca and openssl x509 commands. You must choose your command only based on your requirement. As for lab use cases when we may want to have a common certificate for multiple servers, then we may choose openssl x509 to sign the certificate but if you want to maintain a proper database of all the certificates signed then in such case you should go for openssl ca command to sign the certificates.

I hope I have covered all the scenarios related to this topic, let me know if you have any questions or feedback using the comments section below.

Further Reading man page for openssl ca command man page for openssl x509 command