PKI Infrastructure (01) – Introduction & Certificate Lifetimes

With this first post, I will start a small series of blogs on how to install and configure a Microsoft Public Key Infrastructure (PKI). There are plently of other set of articles on the internet on how to setup PKI solutions on Windows Server and Linux. But I’m writing my own set of articles, also to document my own implementation and to give other people an idea how I’ve down some configs like CRL publications that I have not seen elsewhere. I’m using Powershell and command scripts to deploy the Root CA and the Issuing CA. I also use OpenSSL to create frameworks to create my certificates and document them. I orgininaly started writing this blog post over 2 years ago when I setup my PKI infrastructure on Windows Server 2012 R2, but I have now moved on to Windows Server 2016 for my infrastrucutre and its what I’m going to use for the Root CA, Issuing CA and the Web Server publishing the Certificate Revocation List.

You will also note that my certificate will have much more aggressive expiration that most blogs covering this topic. My reason behind this is to make sure that I need to regularly (each 2 years) work on the PKI Infrastructure to ensure that certs, Issuing CA and Root CA are kept up to date.

Hashing Algorithm are bundled in Cryptographic Service Providers (CSP). A list of the different Microsoft Cryptographic Service Providers (CSP) can be found at Cryptographic Service Providers

My first implementation of a PKI Infrastructure happened in 2003, when I setup a two-tier corporate infrastructure on Windows Server 2003. We started with a Root CA certificate that had a Validity period of 20 years (default used by so many other people). Yet at the half-life of the Root CA in 2013, I needed to refresh the Issuing CA and Root CA. At that point in time the hashing algorithm SHA-1 used in 2003 was being deprecated (SHA-1 Deprecation policy). While changing from a RSA 1024bit to RSA 2048bit key was easy, SHA-2 was not present in the initial Microsoft Cryptographic Service Provider that I selected in 2003. So in 2013 I had to swap for a strong Cryptographic Service Provider causing me to re-install all my PKI from scratch. Selecting the correct Cryptographic Service Provider is primordial.

I used to run two sets of PKI for the past year, one based on the “RSA#Microsoft Software Key Storage Provider” which I labed as a G1 (Generation 1 tier) and the second G2 (Generation 2 tier) based on the Ecliptic Curve Diffie-Hellman (ECDH) algorithm that has been published in the NSA Suite B cryptography. Unfortunately Ecliptic Curve algorithm while being much more secure are not available in most products using certificates. In the past 4 years, I have not been able to use ECDH/ECDSA to encrypt or sign various products. During this implementation of the Two-Tier PKI Infrastructure I will therefore stick to the “RSA#Microsoft Software Key Storage Provider” CSP.

The document Cryptographic Services by Microsoft is a great PKI 101 guide that covers the bases from primitives to secret-key encryption, public-key encryption and digital signatures.

To finish off the first article, I want to talk about Certificates Lifetimes and create the base CApolicy config file for the Root CA and Issuing CA.

The Root Certificate Authority will have a lifetime associated, which can be renewed, but which most likely will be replaced by a new one based on 15 years experience with Public Key Infrastructure.

One of biggest Public Key Infrastructure design question, is the advantages and the disadvantages for the different key size values. The higher the key size, the more secure the certificate is from attackers, but will require more processing to use.  The longer the validity period, the less certificate maintenance required (and potentially some service disruption), but the certificate is more vulnerable to being compromised.

At the Vegas 2009 Microsoft Management Summit (MMS) Chris Adams and Ben Shy from Microsoft presented a breakout session that shared their experience about how they implemented native mode and Internet-based client management in Microsoft.  They shared with customers was their strategy for deciding the key size and validity period.  Their numbers are based on RSA research and how long it would take an attacker to compromise a certificate.  So the higher the key size, the more secure the certificate is (but remember that this comes at the cost of extra processing). Their simple matrix that they presented at MMS looked like this:

  • Key length of 1024:  Validity period = not greater than 6-12 months
  • Key length of 2048:  Validity period = not greater than 2 years
  • Key length of 4096:  Validity period = not greater than 16 years

If we start off the Root Certificate Authority with a Validity of 12 years, the Root CA Key Length should have a key length of 4096, use the Cryptography Next Generation (CNG) Hash Algorithm which is based on SHA-2 and use the implementation hash as SHA256 (which is SHA-2 256bits), SHA384 (SHA-2 384bits) or SHA512 (SHA-2 512bits).

On a Multi-Threaded x64 based platform, the SHA512 is actually faster than the smaller SHA256 (Reference: )

Here is the beginning of my Root CA & Issuing CA configurations. The CApolicy.inf file will be used during the creation of the Root CA certificate or the Issuing CA certificate.

RootCA – CApolicy.inf


For the Issuing CA, which has a validity period of 6 years, we should also set the Key Length to 4096.

IssuingCA – CApolicy.inf


The Issuing Certificate Authority which will issue server/user certificates to be used. The Issuing CA is generally configured to have the half-life of the Root Certificate Authority. Various vendors will now refuse to work with server certificate that have a longer than 2 year certificate lifetime. So you need plan your Root CA, Issuing CA lifetimes properly. Just taking the default is not good enough.

However, you also need to take into account what your CA hierarchy can support. A Certificate Authority cannot issue a certificate with a longer validity period than its own certificate. This one is easy to remember, however, there’s also a ticking time limit because a Certificate Authority cannot issue certificates with a validity period that is longer than its own remaining validity period. This is the reason why we have increased the Root CA validity period from 20 years to 21 years, so that the Issuing CA can stay at 10 years validity.

So lets expand the Root CA and Issuing CA policy.

RootCA – CApolicy.inf

RenewalValidityPeriod = Years
RenewalValidityPeriodUnits = 12

IssuingCA – CApolicy.inf

RenewalValidityPeriod = Years
RenewalValidityPeriodUnits = 6


AlternateSignatureAlgorithm = 0

While the Microsoft Press 2008 PKI documentation refers to the DiscreteSignatureAlgorithm, it should really be the AlternateSignatureAlgorithm. With the support of Cryptography Next Generation (CNG) and the new Suite B signature and encryption algorithms, it is necessary to include information about algorithms in both certificate and certificate requests. If this information is not included, an entity processing the certificate or certificate request may not be able to verify the signature of the object.

The AlternateSignatureAlgorithm option, when assigned a value of 1, enables support for the PKCS#1 V2.1 signature format for both the CA certificate and CA certificate requests. If implemented on a Root CA the Root CA will generate a root certificate that includes the PKCS#1 V2.1 signature format. If implanted on a subordinate CA, the subordinate CA will generate a certificate request that includes the PKCS#1 V2.1 signature format.

Warning: A side effect of using the AlternateSignatureAlgorithm=1 option, means that the PKCS#1 V2.1 signature is changed from SHA384RSA to a RSASSA-PSS. This newer Signature algorithm is not recognized by all certificate implementation. It has been found out that some Citrix implementations break in this config.

There are still plenty of other options that we can insert in the CApolicy.inf configuration, but I will not cover them right now. You will see the end result CApolicy.inf in the corresponding blog entries.

Issuing CA Renewal operation

There is a german proverb “Ubung macht den Meister” that I have always tried to apply to my day to day computer science skills. While dealing with my Public Key Infrastructure in the home datacenter (#HomeDC), this means having a proper multi-tier PKI infrastructure with a Standalone Root CA, an Issuing CA, a PKI Web publishing server for Certificates and Certificate Revocation List. Nearly everyone can setup a PKI infrastructure with Microsoft Windows Server using Next Next Next and a 40 years Root Certificate Authority, but I had to make this a bit more challenging and make it so that it needs a yearly maintenance process to keep my PKI skills fresh.

My PKI Certificate Lifecycle is based on the following schema:

You can find the original diagram on this Microsoft PKI Certificate Lifecycle article. So instead of having a Root CA that is valid for 20 years and an Issuing CA that is valid for 10 years, I went with smaller validity periods, like 8 years for the Root CA and 4 years with the Issuing CA.

I use two different set of Generation PKI Infrastructure. The G1 on which this article is written is using a Root CA with a RSA (4096 Bits) Public Key and a sha512RSA Signature Algorithm for my G1 tier and the same for my Issuing CA. The G2 that you will see on some of the screenshots is based on a Root CA with a Elliptic curve cryptography (ECC) P521 and a sha512ECDSA Signature Algorithm.

Since my infrastructure is now running since 2015, I’m now closing in to the half-time of the Issuing CA validity period. What I decided to do is the following renewal:

  • At T+4 years the Issuing CA certificate will be renewed with a new key pair. This action enforces the 4 year lifetime of the RSA key pair as agreed to when designing the PKI and PKI security. This will create a new CA certificate with a new key pair. This will also force the CA to generate a new CRL file, since there is a new key pair. A CRL signed by the “old” key pair will continue to be generated as long as the CA certificate associated with the “old” key pair is still time valid.

When you do a certificate renewal, the new version has a (1) behind it. The certificate request would now be called Issuing CA G1(1).req

Let’s have a look at the original Issuing CA certificate on the Root CA.

And the Issuing CA detail is

This is now impacting me when I attempt to sign new certificates with a validity of over 24 months. Because those are now limited in their validity until the 4th December 2019.

The first step on the Issuing CA is to Stop Service of the PKI and launch the Renew CA Certificate process. I decided to generate a new public and private key, so my new Issuing CA request file is now named Issuing CA G1(1). Take the certificate request to the Root CA. On the Root CA,  Revoke the current Issuing CA certificate as it’s Superseded and Submit new request of the Issuing CA(1) request file. Issue the new SubCA certificate. We now have a Issuing CA certificate with two fields.

I need to export the signed certificate (I used the PKCS #7 .p7b with certificate path format), move it to the Issuing CA and Import CA Certificate.

In the following steps I’m doing a few more operations on the Root CA. Now that I have Revoked (Yeah with insight I might better have not revoked the original Issuing CA… might need to update this article if I run into issues…) it’s time to do the annual publishing of the Certificate Revocation List (CRL).

I can see in my Root CA CRL now the old revoked Issuing CA certificate serial number.

Moving along on the Issuing CA in the Active Directory, I’m publishing the update Root CA CRL using certutil -dsPublish RootCA.crl RootCA

For the computers and operating systems that are not in the Active Directory and that cannot check the state of the Certificates from the AD, I have a Windows server with the IIS Web server running that publishes the CRLs. This server while having the FQDN of is also referred by the alias on my network. I copied the updated Issuing CA(1) certificate and the Root CA CRL on the directory mapped by the IIS server.

On the Issuing CA in the Enterprise PKI tab, you can ensure that all paths to the Certificates, Certificate Revocation List and Delta CRL work. As you see in the top part of the following screenshot I had not yet copied the Issuing CA(1) certificate. That is corrected in the bottom part of the screenshot.

Having the Issuing CA running again, I forced a Publishing of the Issuing CA CRLs. You can now see them below on the Web server in Purple. There are two sets of the CRL, the ones for the original Issuing CA certificate and the set for the updated Issuing CA(1) certificate.

The files in the red boxes are the ones I manually added to my PKI-WEB repository. They are the annual Root CA CRL and the new Issuing CA G1(1) certificate (I already mentionned it above, I might have been a bit premature in removing the original Issuing CA G1 certificate. I will update this article if I run into serious issues).

I wrote this blog article more for myself as a recap of the operations, as I will have to redo it before 2021. While this is only 4 years down the road, I have already I had the opportunity once in my career to setup a Root CA infrastructure in 2004 with Windows Server 2003 and have to renew it completly 10 years later in 2014. This was a lot more complicated as I had to change the PKI CryptoProvider from the old one only support SHA1 to one that supported SHA2. This is a reminder to all professionals, if you setup a PKI, you might have to work on it again a decade later.



Generating SSL Certificates for vCenter Operations Manager 5.0

Generating SSL Certificates for usage with vCenter, Update Manager and the ESXi host is one of those tasks that keeps being push away. Accepting the self-signed certificates is fine in most situation, but getting validated certificates means a whole lot of pop-ups disappear and surprise surprise, I have also found that the vCenter Operations Manager feels smother and faster.

I recently followed Julian Wood’s excellent series on how to sign certificates for vCenter and Update Manager. Generating the SSL Certificates for vCenter Operations Manager goes along the same lines, but there are changed and maybe some configuration changes on the vCOPS UI-VM.

Julian recommends to install the latest 64-bit version of the OpenSSL Windows Binaries. Retrieve the Win64 OpenSSL v1.0.1 Light for Windows tool on the vCenter with it’s per-requisite Visual C++ 2008 Redistributables (x64) from

Once the OpenSSL v1.0.1 Light is installed, we can add an System Environment Variable, so that the OpenSSL tool can find the path to the OpenSSL configuration file. Because I’m going to use the OpenSSL tool on the vCenter to generate the SSL Certificates for various VMware appliance, I need the variable to stay permanent. From the Control Panel on the vCenter, I add a new System Environment Variable like follows.

Adding the OPENSSL_CONF environment variable in the Control Panel

So that the next time you start the Command Prompt to generate OpenSSL Certificates, the variable is already present.

Checking OPENSSL_CONF variable

One of the best information I learned from Julian’s document is the modification of the openssl.cfg to add the option to use two subjectAltName for the DNS resolution. This allows the user to get a valid certificate when you connect to the vCenter Operations Manager 5.0, using the Fully Qualified Domain Name or simply the short name of the server.

To use this feature you will need to edit the C:\OpenSSL-Win64\bin\openssl.cfg and add “req_extensions = v3_req” to the “[ req ]” section, and add “subjectAltName = DNS:vcops.vsphere.bussink.local,DNS:vcops” to the “[ v3_req]” section. I need to add that I also modify the default key length in the certificate request to 2048 bits.

[box] [ req ]

default_bits        = 2048

req_extensions = v3_req

[ v3_req ]

subjectAltName = DNS:vcops.vsphere.bussink.local, DNS:vcops, DNS:

subjectAltName = DNS:vcops.vsphere.bussink.local, DNS:vcops


Update (29/03/2012): I added to my subjectAltName, the iPAddress of my vCenter Operations Manager UI. You will get the information from the vCenter Managed Object Reference portal ExtensionManager value (See screenshot at the bottom of the post). The entry is of format DNS:

Update (02/04/2012): Thanks to Josh Perkins excellent article “vCenter Operations Manager 5 vCenter Plugin uses IP instead of DNS hostname“. I have removed the IP address subjectAltName in the certificate request in the code above.

To create the Certificate file I used the following commands. Go to the bin directory of the OpenSSL tools. Generate a new Certificate Request while keeping the Cert Private key on your vCenter server. I’m generating the vCOPS private key with the 2048bit RSA algorithms and the SHA256 Message Digest algorithms.

[box] cd C:\OpenSSL-Win64\bin

openssl req -new -nodes -newkey rsa:2048 -sha256 -out vcops.csr -keyout vcops.key


Generate vCOPS Certificate Request

Once we have the Certificate Request for the vCenter Operations Manager, we can submit it to the Public Key Infrastructure for certification. There are two ways to it, once from the command prompt and via the Web interface of the PKI.

Command Prompt Certificate Request

Windows Server 2008 R2 has a simple tool, to submit the Certificate Request directly the Microsoft Root CA (Enterprise Mode).

On my Certificate Authority I have cloned the default WebServer Certificate Template, and named it OpenSSL. I have also modified it’s Validity Period, Renewal Period. See completely at the bottom of this post to get an explanation and description of these changes.

My Microsoft Certificate Authority implementation is configured so that Certificate Requests need to be authorized, so the Submit/Retrieve process is composed of two commands here: certreq -submit and certreq -retrieve, if your Certificate Authority is not setup with validation, the submission/retrieval process is done in a single command.


certreq -submit -attrib “CertificateTemplate:WebServer” vcops.csr


certreq -submit attrib “CertificateTemplate:OpenSSL” vcops.csr[/box]


Submitting vCOPS Certificate Request from Command Prompt

At this point the Certificate has been submitted to the Root CA authority in the domain. Please note the RequestId number when you submit the Certificate Request. Once the Certificate has been authorized and generated you can retrieve it back to the vCenter.

[box]certreq -retrieve 16 vcops.cer [/box]

Retrieve vCOPS Certificate from Command Prompt

If we open the vcops.cer in Windows, we can see that the Certificate has also proper Certificates in the Certification Path. This is important to ensure that browsers can validate the vCOPS Certificate all the way up to the Certificate Authority (with the Issuing CA is it’s an Intermediate Certification Authority).

Verify your vCOPS Certificate for the Certification Path

We now need to build a PKCS#12 container file with the Certificate, the Private Key and output it to the .PFX file.

[box] openssl pkcs12 -export -in vcops.cer -inkey vcops.key -name vcops -out vcops.pfx[/box]

Build vCOPS PKCS12 Container

vCenter Operations Manager 5.0 does not use the PKCS#12 file format, but the PEM format, and requires that the Private Key is not protect by password. So we re-transform the the .PFX with the Private Key into the .PEM format.

[box] openssl pkcs12 -in vcops.pfx -inkey vcops.key -out vcops.pem -nodes[/box]

Transform vCOPS from PKCS12 Container to PEM format

At this point open the Administrator interface of vCenter Operations Manager on the SSL pane, and import the PEM certificate.

The url is https://vcops.<your-domain>/admin/

Importing SSL Certificate in vCOPS


But here comes a tricky part. It’s debugging time.

It is very possible that your Import of the OpenSSL Certificate fails with a General error occured. Like below.

OpenSSL Import General Error Occurred

What I found is that the apache2 Web Server on vCOPS did not like loading my SSL Certificate, because it saw that the certificate was for a FQDN that it could not figure out. I modified the /etc/hosts file to ensure apache2 got the proper hostname while starting up and therefore accepted the OpenSSL Certificates.

Modify /etc/hosts file on vCOPS

In the next screenshot you see the error messages from the apache2 at startup when it cannot figure out it’s name and when it does.

[box]/sbin/service apache2 restart [/box]

vCOPS apache2 startup with default /etc/hosts and modified /etc/hosts


You can always check the vCOPS log files at /var/log/vmware/ for issues.

In the screnshot below we see that I tried to install onces the vcops.pfx format, and then the vcops.pem certificate (@23:38:15), I then restarted the vCOPS Web Service and all is good after 23:46:13.

[box] tail /var/log/vmware/vcops-admin.log[/box]

Checking the vcops-admin.log for SSL install issues

We can now connect to vCenter Operations Manager using the FQDN or the short-name.

Valid SSL Certificate for vCOPS

I have also found that once the OpenSSL Certificate has been changed, that the vCOPS Interface  feels much more reactive.


Appendix 1) – My OpenSSL Certificate Template

On my Active Directory Certificate Services I have cloned the default WebServer Certificate Template, and named it OpenSSL. I have also modified it’s Validity Period, Renewal Period and the need for the Certificate Authority Manager to approve all Certificate Requests.I highly recommend that you set the Validity Period for your Certificate Template. The CA Manager Approval really depends on your environment. As I sometimes do Auto-Enrollment tests for devices, I don’t want to pollute my Root CA with hundreds of superseding certificates.

OpenSSL Certificate Template Properties - Validity Period

OpenSSL Certificate Template Properties – CA Manager Approval



Appendix 2) – Retrieve the Root & Intermediate Certificate Authority Public Key using CertUtil

In this second appendix, I will briefly show how to retrieve the Root Certificate Authority Public Key from the command prompt. You should also retrieve the Intermediate CA if you have one.

[box] certutil -ca.cert -config “domctrl01.vsphere.bussink.local\Bussink Root CA” RootCA.cer[/box]

Retrieve Certificate Authority Public Key RootCA.cer


Update on 16/03/2012. Changed the Win64 OpenSSL v1.0.1 Light tools.

Update 27/03/2012. Added a additional subjectAltName to the Certificate request. But my had my parameters wrong.

Update (27/03/2012): I have added a new subjectAltName on the to my openssl.cfg. I added the FQDN name of my vCenter server in the Certificate request. With vCenter Operations Manager 5.0, you get the integration within the vCenter Client in the Solutions & Applications section. The SSL Certificates will therefore be checked by the vCenter Client against the vCenter FQDN name.

Update 29/03/2012. Thanks for Kinsei for having raises the question on the topic of the SSL Certificate usage via the vCenter Client. The vCenter Operations Manager is connected to the vCenter Server not by an FQDN name, but by an IP Address. You can find the value when you connect to your vCenter server’s Managed Object Reference (mob) settings portal.

https://vcenter/mob/ Content ExtensionManager ExtensionList com.vmware.vcops

 Update (02/04/2012). Here is another update. Josh Perkins has written up a great article on how to ensure that your vCenter uses a FQDN or shortname to speak to your vCenter Operations Manager. This means that administrators and user on the vSphere Client do not get invalid SSL Certificate requests anymore. Thanks Josh !!