mail us  |  mail this page

contact us
training  | 
tech stuff  | 

Creating Self-Signed Certificates and CSRs

  1. Method 1: Quick root and server certificate

  2. Method 2: Quick Single root and server certificate

  3. Method 3: Root CA and Multiple certificates.

  4. Method 4: Creating Subordinate CAs, Intermediate and Cross certificates.

  5. Method 5: - Create SAN (UCC) Certificates (OpenSSL).

  6. Method 6: - Creating various CSRs (OpenSSL).

This section illustrates the use of OpenSSL commands to perform tasks associated with X.509 certificates. To illustrate the certificate process in its entirety it covers generation of certificate Signing Requests (CSRs) and what are loosely called self-signed certificates. Self-signing is one of those terms that needs a little explanation since it has two potential meanings.

At a strict level it means that the issuer and subject attributes in the certificate are the same. In this sense every root certificate is a self-signed certificate. In the second sense it means that the user becomes their own Certificate Authority (CA) and is an alternative to purchasing an X.509 certificate from a recognized CA such as GoDaddy or Thawte (and others) which are already trusted (their root/CA certificates are pre-installed on the user's computer) by most tools, for example, browsers. A user (end-entity) certificate obtained by a browser from a web site during the TLS/SSL Handshake Protocol phase and issued by one of the recognized CAs can be tracked back (and therefore authenticated) by the browser to the signing authority (the CA) by use of the issuer attribute in the certificate. The browser must have the trusted CA's root certificate installed (as well as any intermediate certificates) to avoid any browser error messages. The term trust anchor is used to define such installed certificates and they are typically installed in a keystore structure which may, or may not, be password protected. Trusted CA root certificates for most of the commercial CAs and many National CAs are distributed and installed with browsers such as MSIE, Firefox, Opera etc. or as part of an OS or language, such as Java, system.

The rest of this section deals with the second definition of self-signing - the user becomes their own CA. This form of self-signing can be used either during testing or operationally where, for instance, a user wishes to control access within a private network, a closed user group or some other community of interest. Here the trust relationship, normally associated with an external CA, may be regarded as being implicit due to the nature of the organization signing the certificates.

The first time such a self-signed certificate is presented to a user's TLS/SSL enabled software, such as a browser, and assuming the browser does not have a copy of the relevant root certificate, it will generate a message asking if the user wishes to accept the certificate. Alternatively, the self-signed root certificate can be pre-installed or imported to a user's computer in which case no browser error message will be generated.

Note about Certificate Validity Periods and Key Sizes: Many of the certificates in the following sections are valid for 1 to 3 years. However, most of the commercial root certificates installed in browsers have validity periods of 10+ years! Don't be afraid to use quite lengthy time periods to avoid the pain of renewing certificates. The current RSA key length recommendation (2011) is 2048 bits for lifetimes until 2030 (consequentially many of the current root certificates have expiry dates around 2028 giving them a couple of years to phase in extended bit sizes in time for the 2030 expiry of 2048 bits). RSA Key Strength Note and recommendations over required lifetime. The same keysize (2048 bits) and lifetime recommendation (until 2030) is also contained in US NIST (National Institute or Standards and Technology) Special Publication 800-57 Part 1 Rev2 Table 4.

Process Overview

The following sequences use OpenSSL commands (tested with OpenSSL 1.1.1d) to generate a self-signed X.509 certificates that may be installed and used by TLS/SSL server systems such as Web, FTP, LDAP or mail (SMTP Agent). OpenSSL commands use a bucket load of parameters - including reply defaults, certificate duration and certificate fields - from the openssl.cnf file (/etc/ssl/openssl.cnf - FreeBSD) and if you are going to do serious work with certificates it is well worth looking though this file and editing as appropriate to save some typing.

Note: There are dire text/comment warnings that editing either openssl.cnf or messing around with CA.pl (a useful script file) may cause the sun to fall out of the sky. Make a copy of any such file before you do anything so you can always restore your system to a pristine state in the event anything goes wrong. The bottom line: mess with stuff at your own peril.

The files created when working with certificates will be a mixture of those containing public keys which are generally innocuous and those containing private keys which need to be rigorously protected. Whether both these types of files can be maintained in a single directory structure or not will be a matter of local security policy.

As with all sophisticated software there are usually about 6,000 ways of doing anything - we think there are just three Really Useful Methods (RUM™). The method selected will depend on the local requirements.

Operational Notes: Some of the methods make use of the PERL script CA.pl normally supplied with OpenSSL. When running tests on a new FreeBSD 8.1 install, during which openssl was installed by default (0.9.8n), CA.pl was not installed. If you requested installation of source during the install procedure then it may be found in /usr/src/crypto/openssl/apps/CA.pl. Alternatively, use the ports system (/usr/ports/security/openssl) and then make patch (just downloads and untars the latest version of openssl but does not install it) and then use find ./ -name "CA.pl". Since PERL is no longer installed by default with FreeBSD you may also need to install it. If you are using cygwin on Windows you are out of luck, but (as long as you also installed PERL) you can ontain a copy from the repository at https://github.com/openssl/openssl/blob/master/apps/CA.pl.in. In all cases CA.pl is not essential it just simplifies the process of setting up aan appropriate directory structure. (cygwin also hides the openssl.conf file in cygwin\etc\pki\tls.)

  1. Method 1: Quick root and server certificate

  2. Method 2: Quick Single root and server certificate

  3. Method 3: Root CA and Multiple certificates.

  4. Method 4: Creating Subordinate CAs, Intermediate and Cross certificates.

  5. Method 5: - Create SAN (UCC) Certificates (OpenSSL).

  6. Method 6: - Creating various CSRs (OpenSSL).

Method 1: Root Certificate, Server Certificate

Create a CA, a root certificate that can be imported into a browser for testing purposes and a single server certificate that can be used by a server such as Apache. The standard OpenSSL CA.pl script (which has been moved to /etc/ssl for convenience in the examples - choose an appropriate location) is used to simplify the process:

Note: If a certificate suitable for multiple server name use, for instance, example.com and www.example.com or www.example.net is required follow this procedure instead.

# by default the RSA algorithm is used with 1024 bit keys (2011)
# to change defaults see Method 3: Bullet 1
# create directories and self-signed CA root certificate
cd /etc/ssl
./CA.pl -newca
# the DN sequence requested here will be for the CA
# by default this creates a root certificate in
# demoCA/cacert.pem 
# and the CA's private key in 
# demoCA/private/cakey.pem
# cacert.pem is valid for 3 years

./CA.pl -newreq
# creates a Certificate Signing Request (CSR)
# the requested DN sequence will be for the 
# server name the only important value is
# CN (CommonName) which should be the web or other server name
# such as www.example.com, ldap.example.com or mail.example.com

./CA.pl -sign
# signs the CSR
# and leaves the certificate in 
# /usr/local/openssl/newcert.pem
# newcert.pem is valid for 1 year
# private key in 
# /usr/local/openssl/newkey.pem

# remove the pass phrase from newkey.pem
# to stop server requesting password on load
openssl rsa -in newkey.pem -out keyout.pem

# CAUTION: this file contains a private key and should be 
# given read only permissions for the user

# move and rename as required for the server
# both files newcert.pem and keyout.pem are required
# for example for apache
SSLCertificateFile /path/to/newcert.pem
SSLCertificateKeyFile /path/to/keyout.pem
# examples for OpenLDAP 
TLSCACertificateFile /path/to/cacert.pem
TLSCertificateFile /path/to/newcert.pem
TLSCertificateKeyFile /path/to/keyout.pem

Further explanation and notes. The file demoCA/cacert.pem, which is the root certificate, can be copied and imported to a browser.

Method 2: Single Server Certificate

This is the simplest (one command) way to create a single X.509 certificate that may be used both as a server and a root (CA) certificate. This certificate, because it is self-signed (and the CA:True attribute is present), can be imported into browsers and other client software as a root (CA) certificate. In addition, the same certificate can be configured into Apache or LDAP for use as a server certificate. The DN requested in this sequence references the server that this certificate is being generated for. In particular the CN should define the host service, such as, www.example.com and not the host name of the computer. Thus, if a web service is addressed externally as https://www.example.com but runs on a host called webserver.example.com, CN=www.example.com should be used. The following shows the standard OpenSSL dialog, values in #description# should be replaced with the required value, for example, #server-name# should be replaced with the valid server name being authenticated, say, www.exmple.com or ldap.example.com.

Note: If a certificate suitable for multiple server name use, for example example.com and www.example.com or www.example.net is required follow this procedure instead.

cd /etc/ssl
openssl req -x509 -nodes -days 1059 -newkey rsa:2048 \
 -keyout testkey.pem -out testcert.pem

Generating a 2048 bit RSA private key
.....++++++
..................++++++
writing new private key to 'testkey.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) [AU]:#your-country-code#
State or Province Name (full name) [Some-State]:#your-state-county-province#
Locality Name (eg, city) []:#your-city#
Organization Name (eg, company) [Internet Widgets Pty Ltd]:#your-organization-name#
Organizational Unit Name (eg, section) []:#optional#
Common Name (eg, YOUR name) []:#server-name#
Email Address []:.

# creates testcert.pem as certificate
# and testkey.pem as unencrypted private key
# which should immediately be given 
# read only access to user
# chown user:group testkey.pem
# chmod 0400 testkey.pem

# move and rename as required for the server
# both files testcert.pem and testkey.pem are required
# e.g. for apache
SSLCertificateFile /path/to/testcert.pem
SSLCertificateKeyFile /path/to/testkey.pem
# for OpenLDAP TLS Server (slapd.conf)
TLSCertificateFile /path/to/testcert.pem
TLSCertificateKeyFile /path/to/testkey.pem
# for OpenLDAP TLS Client (ldap.conf)
TLS_CACERT /path/to/testcert.pem

Notes: -x509 causes it to self sign as a root CA. -nodes suppresses the pass phrase dialog. -days 1059 provides a 2 year 329 day certificate.

<ouch> Readers may wonder why any sane person would want to create a certificate valid for 2 years and 329 days. There are two reasons. First, it's possible, so why not. Second, observant readers will have noted that 3 years is 1095 days not the 1059 used in the tests. In short, when running the intial tests we incorrectly transposed the 5 and 9 (put it down to age, eyesight or stupidity as you choose) and rather than rerun the tests with 1095 we let the 1059 stand and have come up with this crummy justification instead. Finally, since the current recommendation for 2048 bit keys suggest they will remain valid until 2030 you could sensibly push the value to (currently, in 2013) -days 6205 (17 years, minus leap year adjustments).</ouch>

Method 3: Root CA and Multiple Certificates

If you are going to generate multiple certificates for use, say, with an internal system then it is worth investing some time and effort. Having tried this using multiple methods this is, IOHO, the simplest. It uses the standard CA.pl script to establish the CA which initialises a bunch of directories and files that are otherwise a serious pain to set up but then uses openssl commands to generate CSRs and sign certificates since this provides greater control over variables and is, relatively, painless.

  1. Location and Preparation Optional to save some typing. Decide where you are going to build your certificate repository. For the sake of illustration we will create it in /etc/ssl and that location will be used throughout. Change as required to suit your circumstances. Move the CA.pl script (use locate CA.pl if you can't find it) to /etc/ssl/CA.pl or wherever you are going to create the certificate repository since we will edit this file. We also rename the script to ca.pl due to a perverse loathing of the shift key but assuming you don't share our pathological characteristics you can substitute CA.pl in the examples.

    The files ca.pl (or CA.pl) and /etc/ssl/openssl.cnf have significant impact on the running of both the script and the openssl commands. We made the following edits for convenience to CA.pl (ca.pl) only the changed lines are shown:

    # WARNING: You should make and keep a clean copy of both
    #          CA.pl and openssl.cnf before messing with either
    # root certificate valid for 10 years - matter of choice
    # but most public CAs provide a root certificate valid until 2028
    $CADAYS="-days 3650";	# 10 years
    # default is $CADAYS="-days 1059";	# 3 years
    
    # changes ca directory name
    $CATOP="./ca";
    # default is $CATOP="./demoCA";
    # if changed needs corresponding change in openssl.cnf
    

    We also made the following changes in /etc/ssl/openssl.cnf to make life easier. Again, only the changed lines are shown:

    # WARNING: You should make and keep a clean copy of both
    #          CA.pl and openssl.cnf before messing with either
    [ CA_default ]
    # mirrors directory change in ca.pl
    dir = ./ca                 # Where everything is kept
    # dir = ./demoCA   # Where everything is kept (default)
    
    # Extension copying option: use with caution
    copy_extensions = copy
    # uncomment above directive if multiple DNS name certificates 
    # are required, else leave commented (default)
    
    # default certificate validity changed to 3 years
    # means you can omit the -days option
    default_days	= 1059 # 3 years
    # default is default_days	= 365 # 1 year
    
    [ policy_match ]
    # add this line in the above section
    # adds L= to issuer and subject DN
    # otherwise it is omitted - matter of taste
    localityName		= optional
    
    [req]
    default_bits = 2048 # current 2011 - 2030 recommendation
    # default_bits = 1024 # original file value
    
    [ req_distinguished_name ]
    # change _default values to save typing
    # edit or add in appropriate place
    countryName_default		= MY 
    stateOrProvinceName_default	= STATE
    localityName_default		= CITY
    0.organizationName_default	= ONE INC
    organizationalUnitName_default	= IT
    
    

    It is worthwhile checking this file for any other values that you might want to change.

  2. Create Certificate Authority The first command creates a Certification Authority (CA) root certificate and some other files used for maintenance. A public-private key pair is created. The public key is written into the root certificate - /etc/ssl/ca/cacert.pem - the private key into /etc/ssl/ca/private/cakey.pem. The default file format is PEM. The DN details requested will be used to populate the issuer and subject fields of the root certificate and into the issuer field of all subsequent signed certificates and should be customized to suit user requirements. The pass phrase is required and used to protect access to the private key - it will be used on all subsequent certificate signings so it might be useful to remember it:

    cd /etc/ssl
    ./ca.pl -newca
    
    CA certificate filename (or enter to create) #ENTER
    
    Making CA certificate ...
    Generating a 2048 bit RSA private key
    .....++++++
    ..................++++++
    writing new private key to './ca/private/cakey.pem'
    Enter PEM pass phrase:
    Verifying - Enter PEM pass phrase:
    -----
    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) [MY]:
    State or Province Name (full name) [STATE]:
    Locality Name (eg, city) [CITY]:
    Organization Name (eg, company) [ONE INC]:CA COMPANY NAME
    Organizational Unit Name (eg, section) [IT]:X.509
    Common Name (eg, YOUR name) []:CA ROOT
    Email Address []:.
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    Using configuration from /etc/ssl/openssl.cnf
    Enter pass phrase for ./ca/private/cakey.pem:
    Check that the request matches the signature
    Signature ok
    Certificate Details:
      Serial Number:
         bb:7c:54:9b:75:7b:28:9c
      Validity
         Not Before: Apr 15 21:07:36 2008 GMT
         Not After : Apr 13 21:07:36 2018 GMT
      Subject:
         countryName               = MY
         stateOrProvinceName       = STATE
         organizationName          = CA COMPANY NAME
         localityName              = CITY
         organizationalUnitName    = X.509
         commonName                = CA ROOT
      X509v3 extensions:
       X509v3 Subject Key Identifier: 
        54:0D:DE:E3:37:23:FF...
       X509v3 Authority Key Identifier: 
        keyid:54:0D:DE:E3:37...
        DirName:/C=MY/ST=STATE/O=CA COMPANY NAME/L=CITY/OU=X.509/CN=CA ROOT
        serial:BB:7C:54:9B:75:7B:28:9C
       X509v3 Basic Constraints: 
        CA:TRUE
    Certificate is to be certified until Apr 13 21:07:36 2018 GMT (3650 days)
    
    Write out database with 1 new entries
    Data Base Updated
    

    Note Lines may have been truncated and omitted (replaced with ... in both cases) above since the deleted material does nothing to aid understanding of the process.

    A standard directory structure has been created:

    ca                   # cacert.pem (root certificate)
                         # serial (tracks serial numbers)
                         # crlnumber (serial number for CRLs)
                         # index.txt 
    ca/private/cakey.pem # private ca key
    ca/newcerts          # copy of all certs created
    ca/crl               # optional location for CRLs created
    ca/certs             # optional location for certs created
    

    The root certificate created (ca/cacert.pem) is valid for 10 years (3650 days) based on the ca.pl file edit. The root private key (ca/private/cakey.pem is protected by its PEM pass phrase but should still be protected by the lowest permissions possible (defaulted to 0644 which is unnecessarily high). The Challenge Password is a simple password that may be used to guard access to Certificates, CSRs and the subsequent X.509 certificate. Most, if not all, commercial CAs do not want one or the accompanying Optional Company Name and all the examples leave the field blank. If you want to permanently disable the prompts edit /etc/ssl/openssl.cnf:

    [ req_attributes ]
    # comment out all following lines
    #challengePassword		= A challenge password
    #challengePassword_min		= 4
    #challengePassword_max		= 20
    
    #unstructuredName		= An optional company name
    
  3. Create a certificate signing request (CSR). The requested DN in this sequence will appear in the subject field of the final certificate.

    This command may also be used to generate a CSR (Certificate Signing Request) for a commercial CA and since most CAs do not want a password just hit ENTER at the A challenge password prompt (see notes above about permanently removing the prompts). The optional emailAddress value is also left blank. Mostly because it achieves no purpose in a server certificate and indeed most commercial CAs request it is left blank.

    openssl req -nodes -new -newkey rsa:2048 \ 
    -keyout ca/private/cert1key.pem -out ca/certs/cert1csr.pem
    
    Generating a 2048 bit RSA private key
    ...................++++++
    ............++++++
    writing new private key to 'ca/private/cert1key.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) [MY]:
    State or Province Name (full name) [STATE]:
    Locality Name (eg, city) [CITY]:
    Organization Name (eg, company) [ONE INC]:
    Organizational Unit Name (eg, section) [IT]:
    Common Name (eg, YOUR name) []:www.example.com
    Email Address []:.
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    

    This creates a new CSR (in /etc/ssl/ca/certs/cert1csr.pem) which must then be signed using the CA's private key and a private key (not secured by a pass phrase - -nodes option - suitable for use in a server application) in /etc/ssl/ca/private/cert1key.pem. The CN value (www.example.com in the example above) is the service name used by the application. It could have been ldap.example.com or any other similar name. Note also that if the normal server access is https://www.example.com this certificate will work - however if the access will also use https://example.com then you need to force use of a subjectAltName certificate attribute by using this procedure before creating the CSR (and use ServerAlias directive in the VirtualHost section for Apache). The service name should not be confused with the server's host name. Thus, if a web service is addressed externally as https://www.example.com but runs on a host called webserver.example.com, www.example.com should be used for the CN.

    To view the certificate request:

    openssl req -in ca/certs/cert1csr.pem - noout -text
    
    Certificate Request:
     Data:
      Version: 0 (0x0)
      Subject: C=MY, ST=STATE, L=CITY, O=ONE INC, OU=IT, CN=www.example.com
      Subject Public Key Info:
      Public Key Algorithm: rsaEncryption
      RSA Public Key: (1024 bit)
       Modulus (1024 bit):
        00:ae:19:86:44:3c:dd...
        ...
        99:20:b8:f7:c0:9c:e8...
        38:c8:52:97:cc:76:c9...
       Exponent: 65537 (0x10001)
       Attributes:
         a0:00
     Signature Algorithm: sha1WithRSAEncryption
      79:f5:20:45:6c:ec:8e:ae...
      ...
      bd:61:cd:c5:89:7c:e0:0d...
      40:7d
    

    Note Lines have been truncated and omitted (replaced with ... in both cases) above since the deleted material does nothing to aid understanding of the process.

  4. Create and Sign the end-user certificate This takes the input CSR (ca/certs/cert1csr.pem) and creates the end user (end-entity) certificate (ca/certs/cert1.pem):

    openssl ca -policy policy_anything \
    -in ca/certs/cert1csr.pem -out ca/certs/cert1.pem
    
    Using configuration from /usr/local/openssl/openssl.cnf
    Enter pass phrase for ./ca/private/cakey.pem:
    Check that the request matches the signature
    Signature ok
    Certificate Details:
      Serial Number:
        bb:7c:54:9b:75:7b:28:9d
      Validity
        Not Before: Apr 15 22:21:10 2008 GMT
        Not After : Mar 10 22:21:10 2011 GMT
      Subject:
        countryName               = MY
        stateOrProvinceName       = STATE
        localityName              = CITY
        organizationName          = ONE INC
        organizationalUnitName    = IT
        commonName                = www.example.com
     X509v3 extensions:
      X509v3 Basic Constraints: 
       CA:FALSE
      Netscape Comment: 
       OpenSSL Generated Certificate
      X509v3 Subject Key Identifier: 
       EE:D9:4A:74:03:AC:FB:2C...
      X509v3 Authority Key Identifier: 
       keyid:54:0D:DE:E3:37:23...
    
    Certificate is to be certified until Mar 10 22:21:10 2011 GMT (1059 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
    

    Note Lines have been truncated and omitted (replaced with ... in all cases) above since the deleted material does nothing to aid understanding of the process.

    The resulting certificate issuer field is from the root certificate (ca/cacert.pem) and the subject field from the CSR. The command line defaults many values from openssl.cnf: the validity period (default_days =), the signing key (private_key =) and the issuer from the root certificate (certificate =). The -policy policy_anything option may be necessary depending on your requirements. It references the policy_anything section defined in the openssl.cnf file which allows any fields in the subject DN certificate to have different values from those in the issuer DN field. If not present it defaults to -policy policy_match which places restrictions on C=, ST= and O= RDN values.

    To view the resulting certificate:

    openssl x509 -in ca/certs/cert1.pem -noout -text
    
    Certificate:
     Data:
      Version: 3 (0x2)
      Serial Number:
       bb:7c:54:9b:75:7b:28:9d
      Signature Algorithm: sha1WithRSAEncryption
      Issuer: C=MY, ST=STATE, O=CA COMPANY NAME, L=CITY, OU=X.509, CN=CA ROOT
      Validity
       Not Before: Apr 15 22:21:10 2008 GMT
       Not After : Mar 10 22:21:10 2011 GMT
      Subject: C=MY, ST=STATE, L=CITY, O=ONE INC, OU=IT, CN=www.example.com
      Subject Public Key Info:
       Public Key Algorithm: rsaEncryption
       RSA Public Key: (1024 bit)
        Modulus (1024 bit):
         00:ae:19:86:44:3c:dd...
         ...
         99:20:b8:f7:c0:9c:e8...
         38:c8:52:97:cc:76:c9...
        Exponent: 65537 (0x10001)
     X509v3 extensions:
      X509v3 Basic Constraints: 
       CA:FALSE
      Netscape Comment: 
       OpenSSL Generated Certificate
      X509v3 Subject Key Identifier: 
       EE:D9:4A:74:03:AC:FB:2C...
      X509v3 Authority Key Identifier: 
       keyid:54:0D:DE:E3:37:23...
    
     Signature Algorithm: sha1WithRSAEncryption
      52:3d:bc:bd:3f:50:92...
      ...
      51:35:49:8d:c3:9a:bb...
      b8:74
    

    Note Lines have been truncated and omitted (replaced with ... in both cases and which never appear legitimately in these fields) in the above since the deleted material does nothing to aid understanding of the process.

    Useful Commands

    Checking or viewing Certificates Corruption can occur so the certificate can be verified using the following commands:

    openssl x509 -in certificate-name.pem -noout -text 
    # display whole certificate
    
    openssl x509 -in certificate-name.pem -noout -dates
    # validity dates only
    
    openssl x509 -in certificate-name.pem -noout -purpose
    # list of all purposes certificate may be used for
    
    openssl x509 -in certificate-name.pem -noout -purpose - dates
    # list validity period and purpose
    
  5. Importing a self-signed root certificate The PEM format file created in step 2 above (ca/cacert.pem) may be directly imported into MSIE and Firefox to inhibit them from prompting for untrusted certificates. Follow procedure.

Method 4: Create Subordinate CAs, Intermediate and Cross Certificates

Method 3 creates a simple two certificate chain comprising an end-entity (server) certificate and a root CA certificate. Method 4 explores how we can add to this structure, for reasons best known to ourselves, to create a subordinate CA, perhaps a second root CA and create a whole variety of Cross and Intermediate certificates based on this structure:

  1. Base Setup: Run steps 1 and 2 of Method 3. This simply creates a directory structure and our first root CA. If you have already run the whole of Method 3, none of the file names created in the next steps will clash - so nothing will be lost and your system will not self-destruct. At the end of this process the following directories will have been created:

    ca                   # cacert.pem (root certificate)
                         # serial (tracks serial numbers)
                         # crlnumber (serial number for CRLs)
                         # index.txt 
    ca/private/cakey.pem # private ca key
    ca/newcerts          # copy of all certs created
    ca/crl               # optional location for CRLs created
    ca/certs             # optional location for certs created
    

    Strategy Note: Openssl commands take many of their advanced parameters from the configuration file (openssl.cnf). Up to this point we have suggested that changes should be made to this standard file since they are typically used consistently accross all commands. From this point on this is not the case. Instead, we recommend that you copy and rename the standard configuration file (openssl.cnf) to a new configuration file with an appropriate name (that you can remember) and use the -config filename argument to pick up the appropriate config file based on usage. It's quicker (eventually), less confusing (eventually) and re-useable (always).

  2. Create a subordinate CA:

    Create a new directory called, say, subca and subca/private (giving this directory the same permissions as ca/private). This step simply keeps things organized (kinda):

    cd /etc/ssl
    mkdir ca/subca
    mkdir ca/subca/private
    # create necessary empty database file for subca signer
    touch ca/subca/index.txt
    

    Edit openssl.cnf and create a section called [ sub_ca] - it can be anywhere in the file but for convenience we have shown it located above the [ user_certs ] section. The various entries in this section will be used to override the normal options used when a certificate is signed.

    # new section
    [ sub_ca ]
    basicConstraints=CA:TRUE
    # alternatively
    # basicConstraints= CA:TRUE,pathlen:0
    # pathlen:0 constrains the subCA to
    # only sign end-entity certificates
    
    # optional entry and string could be
    # nsComment="Most Trusted Certificate in the World"
    nsComment="OpenSSL Generated Certificate"
    # next two are normal for all non-root certificates
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid,issuer
    
    # next line just shows where sub_ca section is positioned in file
    [ user_cert ]
    
  3. Create the subordinate CA certificate:

    Create a CSR for the subordinate CA and sign it with the root CA certificate:

    # NOTE: These steps will use the root CA created in Method 3 step 1 and 2
    
    # create the CSR for the subordinate CA
    openssl req -new -keyout ca/subca/private/subca1key.pem \
      -out ca/subca/subca1csr.pem
    Generating a 2048 bit RSA private key
    ...................++++++
    ............++++++
    writing new private key to 'ca/subca/private/subca1key.pem'
    Enter PEM pass phrase:
    Verifying - Enter PEM pass phrase:
    -----
    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) [MY]:
    State or Province Name (full name) [Some-State]:
    Locality Name (eg, city) [Some City]:
    Organization Name (eg, company) [My Company Name]:
    Organizational Unit Name (eg, section) []:Certs
    Common Name (eg, YOUR name) []:subCA1
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    
    # Notes:
    # 1. Organizational Unit Name is not important simply descriptive
    # 2. Common Name is the name to be given to the subordinate CA 
    
    ## now sign this request using the root CA and force the defined extensions
    ## using -extensions sub_ca
    
    openssl ca -policy policy_anything -in ca/subca/subca1csr.pem \
      -out ca/subca/subca1cert.pem -extensions sub_ca
    	
    # display the resulting certificate
    openssl x509 -in ca/subca/subca1cert.pem -noout -text
    Certificate:
     Data:
      Version: 3 (0x2)
      Serial Number:
         c6:bd:b2:ce:22:bc:4d:57
      Signature Algorithm: sha1WithRSAEncryption
      Issuer: C=MY, ST=Some-State, O=My company name, OU=Certs, CN=Root CA1
      Validity
       Not Before: Dec 9 20:40:18 2011 GMT
       Not After : Dec 6 20:40:18 2021 GMT
      Subject: C=MY, ST=Some-State, L=Some City, O=My company name, OU=Certs, CN=subCA1
      Subject Public Key Info:
       Public Key Algorithm: rsaEncryption
       RSA Public Key: (2048 bit)
        Modulus (2048 bit):
         00:a9:f3:02:01:c9...
         01:b6:27:c8:a0:9c...
         ...               
         f0:37:71:5d:e3:c7:3d:59:ff...
         55:87
        Exponent: 65537 (0x10001)
       X509v3 extensions:
        X509v3 Basic Constraints: 
         CA:TRUE
        X509v3 Key Usage: 
         Certificate Sign, CRL Sign
        Netscape Comment: 
         OpenSSL Generated Certificate
        X509v3 Subject Key Identifier: 
         58:47:30:77:3F:EF...
        X509v3 Authority Key Identifier: 
         keyid:FB:7B:FB:7B...
    
     Signature Algorithm: sha1WithRSAEncryption
      43:b5:e2:8d:4d:07:56...
      ...
      12:2c:a2:7c:eb:dc:45...
      e0:f3:2b:72
    

    Note Lines have been truncated and omitted (replaced with ... in both cases) in the above since the deleted material does nothing to aid understanding of the process.

    The four X509v3 extensions are the direct consequence of the -extensions sub_ca argument and override the normal certificate features. If the root CA is required to sign a normal end-entity certificate just omit this argument. Technically, the resulting certificate (ca/subca/subca1cert.pem) is a cross-certificate because both the signer and the certificate being signed have basicConstraints with cA True.

  4. Sign an end-entity certificate with the subordinate CA:

    To sign an end-entity certificate using the subordinate CA we first need to copy and save openssl.cnf to another name, say, subca1.cnf. Now make the following edits to subca1.cnf (these changes simply tell openssl where to obtain various files relating to the subCA whereas the standard openssl.cnf will continue to refer to the root CA information):

    [ CA_default ]
    # only values to be changed are shown
    database	= $dir/subca/index.txt	# database index file.
    certificate	= $dir/subca/subca1cert.pem 	# The subCA certificate
    # the parameter below will cause all certicates from both the root 
    # and the sub CA to use the same numbering sequence
    # to change copy ca/serial to ca/subca/serial and modify parameter
    serial		= $dir/serial 		# The current serial number
    # if you need to keep CRLs separate or leave unchanged
    crl_dir		= $dir/subca/crl		# Where the issued crl are kept
    crlnumber	= $dir/subca/crlnumber	# the current crl number
    
    # must be commented out to leave a V1 CRL
    crl		= $dir/subca/crl.pem 		# The current CRL
    
    private_key=$dir/subca/private/subca1key.pem # The subCA private key
    RANDFILE	= $dir/subca/private/.rand	# private random number file
    

    Now create an end-entity CSR and sign it with the subCA keys:

    # create CSR
    openssl req -new -nodes -keyout ca/private/user1key.pem \
      -out ca/certs/user1csr.pem
    # sign it with the subCA key by using -config subca1.cnf
    openssl ca -policy policy_anything -in ca/certs/user1csr.pem \
      -out ca/certs/user1cert.pem -config subca1.cnf
    # print the resulting certificate
    openssl x509 -in ca/certs/user1cert.pem -noout -text
    Certificate:
     Data:
      Version: 3 (0x2)
      Serial Number:
       c6:bd:b2:ce:22:bc:4d:58
      Signature Algorithm: sha1WithRSAEncryption
      Issuer: C=MY, ST=Some-State, L=Some City, O=My company name, OU=Certs, CN=subCA1
      Validity
        Not Before: Dec 9 21:06:43 2011 GMT
        Not After : Dec 6 21:06:43 2021 GMT
      Subject: C=MY, ST=Some-State, L=Some City, O=My company name, OU=Server, CN=www.example.com
      Subject Public Key Info:
      Public Key Algorithm: rsaEncryption
       RSA Public Key: (2048 bit)
        Modulus (2048 bit):
         00:c3:f4:dc:07:08:30:3a...
         ...
         a8:45:fd:c5:d7:a4:04:82...
         af:dd
        Exponent: 65537 (0x10001)
      X509v3 extensions:
       X509v3 Basic Constraints: 
        CA:FALSE
       Netscape Comment: 
        OpenSSL Generated Certificate
       X509v3 Subject Key Identifier: 
        B1:5A:23:4E:C8:2B:FD:98...
       X509v3 Authority Key Identifier: 
        keyid:58:47:30:77:3F:EF...
    
     Signature Algorithm: sha1WithRSAEncryption
      50:4b:8e:50:8f:fa:f4:98...
      ...
      3d:97:52:28:1f:a6:9d:2e...
      ac:58:be:eb
    

    Note Lines have been truncated and omitted (replaced with ... in both cases) in the above since the deleted material does nothing to aid understanding of the process.

    The certificate issuer in this case is subCA1 not root CA1 as when signing the subordinate CA certificate request. To allow chain validation of the end-entity certificate BOTH the root CA certificate (ca/cacert.pem) and the subordinate CA certificate (ca/subca/subca1cert.pem) must be imported into the browser.

  5. Other Possibilities:

    Using variations of this technique, a second root CA (root CA2) could be created (another copy of openssl.cnf would be needed clearly), or a second subordinate CA (subCA2 - again with a unique .cnf file). In short, all sorts of ghastly permutations are possible.

Method 5: - Create SAN (UCC) or Multi-Server Certificates

If a certificate may be used by a host which has more than one DNS name, say, https://www.example.com and https://example.com or even www.example.net then you need to force the Certificate Signing Request (CSR) to use the subjectAltName certificate attribute. To do this, edit the openssl.cnf file as shown below (only changed lines shown):

# first find the [CA_Default] section
[CA_Default]
....
# uncomment or add
copy_extensions = copy
# this causes the ca function to copy the extension fields
# from the CSR and should be done on the host which handles
# the CSRs to create the certificates

# now find [v3_req] section
[v3_req]
...
# add the following line with host names modified as required
subjectAltName = "DNS:www.example.com, DNS:example.com,DNS:example.net"
# this should be done on the host that generates the CSR

When you run any CSR request add -reqexts "v3_req" to the arguments only when you need to include the additional subjectAltName fields. While the example above shows 3 names being added in practice it can be any number. Each entry has the format DNS:hostname.domain.name, multiple entries are comma separated and the whole lot is enclosed in quotes. The line following shows the CSR request in Step 3 of Method 3 with the additional argument:

openssl req -nodes -new -newkey rsa:2048 \ 
-keyout ca/private/cert1key.pem -out ca/certs/cert1csr.pem -reqexts "v3_req"

If the -reqexts argument is not added to the CSR a normal single server name certificate is created. This process only works with method 3 above and provides the most flexible approach.

Note: If you are going to produce a number of certificates each of which has different multiple server names then a better strategy may be to simply copy and rename the standard configuration file (openssl.cnf) to something sensible and then use the -config filename argument to pick up each file when required. You can have any number of such config files - as long as you remember their names and functionality.

If you want to create multi-server certificates with Method 1 or 2 then in addition to the above edits, make a further edit to openssl.cnf:

# find the [req] section
[req]
....
# add or uncomment
req_extensions = v3_req

This modification has the effect of adding the subjectAltName certificate attribute unconditionally to every CSR.

GO UP Image

Method 6: - Create Common CSRs for Signing by CAs (OpenSSL)

Most commercial CA website give the choice of providing either a Certificate Signing Request (CSR) (in which case the CA will generate the certificate and provide an intermediate/CA bundle file) or using a wizard/form (in which case the CA will provide the certificate, a private key and an intermediate/CA bundle file). For reasons of operational flexibility, organizational policy or good 'ole paranoia many opt to generate a CSR and its corresponding private key. This section provides simple OpenSSL comands to cover the most common requirements.

GO UP Image



Problems, comments, suggestions, corrections (including broken links) or something to add? Please take the time from a busy life to 'mail us' (at top of screen), the webmaster (below) or info-support at zytrax. You will have a warm inner glow for the rest of the day.

Tech Stuff

RSS Feed Icon

If you are happy it's OK - but your browser is giving a less than optimal experience on our site. You could, at no charge, upgrade to a W3C standards compliant browser such as Firefox

Search

web zytrax.com

Share

Icons made by Icomoon from www.flaticon.com is licensed by CC 3.0 BY
share page via facebook tweet this page

Page

email us Send to a friend feature print this page Display full width page Decrease font size Increase font size

Standards

ISO (International)
IEC (International)
ANSI (US)
DIN (Germany)
ETSI (EU)
BSI (UK)
AFNOR (France)

Telecom

TIA (US)
ECIA (US)
ITU (International)
IEEE (US)
ETSI (EU)
OFCOM (UK)

Internet

IETF
IETF-RFCs
IANA
ICANN
W3C

Electronics

JEDEC
ECIA (US)

Site

CSS Technology SPF Record Conformant Domain
Copyright © 1994 - 2021 ZyTrax, Inc.
All rights reserved. Legal and Privacy
site by zytrax
Hosted by super.net.sg
web-master at zytrax
Page modified: December 05 2019.