> Note: I am not an expert on PKI.  This is a compendium of various recommendations and actions that Microsoft, NIST, and other well respected PKI and cryptography experts have said.  If you see something that requires even the slightest revision, do let me know.

Before I get into configuring the CA and its subs, it's good to know that even though MSFT's CryptoAPI requires a self-signed root, some non-MSFT software may follow RFC 3280 and allow any CA to be the trusted root for validation purposes.  One reason may be that the non-MSFT software prefers a lower key length.

Here are some configuration notes & guidance on setting up a CA ROOT and the Subs:

**Storing the CA's Private Key**

* Best: Store the key on a HSM that supports key counting.  Every time the CA's private key is used, the counter will be increased.  This improves your audit profile.

* Good: Store the Private key on a smart card. Though I'm unaware of any Smart Card that offers key counting, enabling key counting [may give you unexpected results in the event log][1]

* Acceptable: Store the private key in Windows DPAPI.  Ensure that these keys and the Key Enrollment agent don't end up in [Roaming Credentials][2].  See also: [How to enumerate DPAPI and Roaming Credentials][3]

**Key Length**

* Don't use 1024 as a key length... NIST phased it out in 2011, MSFT won't ever add it into your [Trusted Root CA store][4] since it won't meet the minimum accepted technical criteria.

* Root CAs *that supports legacy apps* should never be larger than 2048 bits.  Reason: MSFT Support sees many cases where [Java apps or network devices only support key sizes of 2048 bytes][5].  Save the higher bit lengths to CAs that are constrained for a specific purpose (Windows vs Network devices) etc.

* The NIST [recommends 2048 or 3072 bits.][6]  ECC is supported, though it may cause issues with device interoperability.

* Plan for the strongest possible encryption (key length) throughout the PKI, [otherwise expect mixed security benefits][7]. 

* Mobile clients have issues (High CPU) or incompatibility with large keys

**Choosing a Hash**

* You may want to imitate the [Federal PKI Management Authority][8] and set up two PKI roots.  One modern SHA-256 for all devices that support it, and one legacy SHA-1.  Then use cross certificates to map between the two deployments.

* Review this [SHA-2 compatibility list for Microsoft software][9]

Notably: 

* Windows 2003 and [XP clients may need a patch for SHA2 Algorithms][10] which include SHA256, SHA384, and SHA512. [See more technical information][11]

* Authenticode and S/MIME with SHA2 hashing is not supported on XP or 2003

* "Regarding SHA-224 support, SHA-224 offers less security than SHA-256 but takes the same amount of resources. Also SHA-224 is not generally used by protocols and applications. The NSA's Suite B standards also do not include it." [source][12]

* "Do not use SHA2 suite anywhere in the CA hierarchy if you plan to have XP either trust the certificate, validate the certificate, use the certificate in chain validation, or receive a certificate from the CA. Even though XP SP3 allows validation of certiifcates that use SHA2 in the CA hierarchy, and KB 968730 allows limited enrollment of certificates that are signed by a CA using SHA2, any use of discrete signatures blocks out XP entirely." ([source][13])

**Choosing a Cryptographic Provider**

* I'm not sure which one to choose so [I'll post this link to a list of providers][14]

**Enable random serial number generation**

As of 2012, this is required if you use MD5 as a hash, otherwise the private key can be discovered.  It's still a good idea if SHA1 or greater is used.  See [certificate hacks via missing random data][15].  Also see [this Windows 2008R2 "how to"][16] for more information.

**Enable CRL checking**

Normally, a Windows Server 2003 CA will always check revocation on all certificates in the PKI hierarchy (except the root CA certificate) before issuing an end-entity certificate. To disable this feature, use the following command on the CA, and then restart the CA service:

     certutil –setreg ca\CRLFlags +CRLF_REVCHECK_IGNORE_OFFLINE  


**CRL Distribution Point**

Getting the CRL "right" is pretty important since it's up to each application to do the CRL check.  For example smart card logon on domain controllers always enforce the revocation check and will reject a logon event if the revocation check cannot be performed or fails.

Note If any certificate in the chain cannot be validated or is found to be revoked, the entire chain takes on the status of that one certificate.

* A self-signed root CA should not list any CDPs.  Most windows applications don't enable the CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT flag and therefore ignore the CDP ([this is the default validation mode][17]).  If the flag is enabled, and the CDP is blank for the self signed root cert, no error is returned.

* Don't use HTTPS and LDAPS.  These URLs are no longer supported as distribution point references. Reason is that HTTPS and LDAPS URLs use certificates that may or may not be revoked. The revocation checking process can result in revocation loops when HTTPS or LDAPS URLs are used. To determine if the certificate is revoked, the CRL must be retrieved. However, the CRL cannot be retrieved unless the revocation status of the certificates used by HTTPS or LDAPS is determined.

* Don't use LDAP- Although AD DS enables publication of CRLs to all domain controllers in the forest implement HTTP instead of LDAP for revocation information publication. Only HTTP enables the use of the ETag and Cache-Control: Max-age headers providing better support for proxies and more timely revocation information. In addition, HTTP provides better heterogeneous support as HTTP is supported by most Linux, UNIX, and network device clients.

* Not using LDAP permits the revocation window to be smaller.  When using AD LDAP to replicate CA information, the revocation window couldn't be less than the time for all sites in AD to get the CA update.  Oftentimes this replication could take up to 8 hours... that is 8 hours until a smartcard user's access is revoked.  'Todo: the new recommended CRL refresh time is: ?????`

* Make all the URLs highly available (aka don't include LDAP for external hosts).  Windows will slow down the validation process for up to 20 seconds and [retry the failed connection][18] repeatedly at least as frequently as every 30 min.   I suspect that [Pre-fetching][19] will cause this to occur even if the user isn't actively using the site. 
 
* Monitor the size of your CRL.  If the CRL object is so large that CryptoAPI is not able to download the object within the allotted maximum timeout threshold, [a “revocation offline” error is returned and the object download is terminated.][20]

>  Note: CRL distribution over HTTP with ETAG Support may cause issues with IE6 when using Windows 2003 / IIS6, where the TCP connection is continually reset.


* (Optional) Enable Freshest CRL:  This non-critical extension lists the issuers and locations from which to retrieve the delta CRLs. If the “Freshest CRL” attribute is neither present in the CRL nor in the certificate, then the base CRL will be treated as a regular CRL, not as part of a base CRL/delta CRL pair.

The Microsoft CA does not put the “Freshest CRL” extension into issued certificates. However, it is possible to add the “Freshest CRL” extension to an issued certificate. You would have to write code to add it to the request, write a custom policy module, or use `certutil –setextension` on a pending request. For more information about advanced certificate enrollment, see the “Advanced Certificate Enrollment and Management” documentation on the [Microsoft Web site][21]

> Warning If delta CRLs are enabled at a CA, both the base CRL and delta
> CRL must be inspected to determine the certificate’s revocation
> status. If one of the two, or both, are unavailable, the chaining
> engine will report that revocation status cannot be determined, and an
> application may reject the certificate.


**Authority Information Access**

This field allows the Certificate validation subsystem to download additional certificates as needed if they are not resident on the local computer.

*  (I've seen conflicting advice on this:) A self-signed root CA should not list any AIA locations  

* A maximum of five URLs are allowed in the AIA extension for every certificate in the certificate chain. In addition, a maximum of 10 URLs for the entire certificate chain is also supported. This limitation on the number of URLs was added to mitigate the potential use of “Authority Info Access” references in denial of service attacks.

* Don't use HTTP**S** and LDAP**S**.  These URLs are no longer supported as distribution point references. Reason is that HTTPS and LDAPS URLs use certificates that may or may not be revoked. The revocation checking process can result in revocation loops when HTTPS or LDAPS URLs are used. To determine if the certificate is revoked, the CRL must be retrieved. However, the CRL cannot be retrieved unless the revocation status of the certificates used by HTTPS or LDAPS is determined.

**Enable OCSP Validation**

The OCSP responder is conventionally located at: `http://<fqdn of the ocsp responder>/ocsp`.  This url needs to enabled in the AIA.  [See these instructions for Windows.][22]

**OCSP Cache duration**

All OCSP actions occur over the HTTP protocol and therefore are subject to typical HTTP proxy cache rules.
 
Specifically the `Max-age` header defines the maximum time that a proxy server or client will cache a CRL or OCSP response before using a conditional GET to determine whether the object has changed.  Use this information to configure the web server to set the appropriate headers.  Look elsewhere on this page for AD-IIS specific commands for this.


**Define a policy in issued certificates**

The parent CA defines whether or not to allow CA certificate policies from sub CAs.  It is possible to define this setting when a issuer or application policy needs to be included in a sub CA.

Example polices include an EKU for SmartCards, Authentication, or SSL/Server authentication.


**Monitor the DN length enforcement**

The original CCITT spec for the OU field says it should be limited to 64 characters. Normally, the CA enforces x.500 name length standards on the subject extension of certificates for all requests. It is possible that deep OU paths may exceed normal length restrictions.


**Cross Certificate Distribution Points**

This feature assists where environments need to have two PKIs installed, one for legacy hardware/software that doesn't support modern cryptography, and another PKI for more modern purposes.


**Restrict the EKU**

In contrast with RFC 5280 that states “in general, [sic] the EKU extension will appear only in end entity certificates." it's a good idea to put [constraints on the CA Key usage][23].

A typical stand-alone CA certificate will contain permissions to create Digital Signatures, Certificate Signing, and CRL signing as key values.  This is part of the issue with the FLAME security issue.

In addition the MSFT smart card implementation has interesting constraints around validating EKU.   

If you're interested in having any EKU restrictions you should see [this answer regarding OIDs][24] and [this regarding contrained certificates][25]

**Qualified Subordination for Intermediate CAs**

* To limit the types of certificates a subCA can offer see [this link][26], and [this one][27]

**Authority Key Identifier / Subject Key Identifier**

Note If a certificate’s AKI extension contains a KeyID, CryptoAPI requires the issuer certificate to contain a matching SKI. This differs from RFC 3280 where SKI and AKI matching is [optional][28].  (todo: Why would someone choose to implement this?)

![AKI matching to find key parent][29]
 

**Give the Root and CA a meaningful name**

People will interact with your certificate when importing it, reviewing imported certificates, and troubleshooting.  MSFT's recommended practice and [requirement][30] is that the root has a meaningful name that identifies your organisation and not something abstract and common like CA1.

This next part applies to names of Intermediate/subCA's that will be constrained for a particular purpose: Authentication vs Signing vs Encryption

Surprisingly, End users and technicians who don't understand PKI's nuances will interact with the server names you choose more often than you think if you use S/MIME or digital signatures (etc).

I personally think it's a good idea to rename the issuing certificates to something more user friendly such as `"Company Signer 1"` where I can tell at a glance 

* Who is the signature going to come from (Texas A&M or their rival)
* What is it used for? Encryption vs Signing

> It's important to tell the difference between a message that was encrypted between two parties, and one that was signed.  One example where this is important is if I can get the recipient to echo a statement I send to them.  User A could tell user B "A, I owe you $100".  If B responded with an echo of that message with the wrong key, then they effectively digitally notarized (vs just encrypting) a fictitious $100 debt.

Here is a sample user dialog for S/MIME.  Expect similar UIs for Brower based certificates.  Notice how the Issuer name isn't user friendly.

![Select a SMIME certificate.. really?][31]

**Alternate Encodings**

Note: Speaking of names, if any link in the chain uses an alternate encoding, then clients may not be able to verify the issuer field to the subject.  Windows does not normalize these strings during a comparison so make sure the names of the CA are identical from a binary perspective (as opposed to the RFC recommendation).

![Name matching to find key parent][32]

**High Security/Suite B Deployments**

* Here is [information regarding the Suite B algorithms supported in Windows 2008 and R2][33]


    ALGORITHM                                          SECRET           TOP SECRET

    Encryption:
    Advanced Standard (AES)                            128 bits         256 bits

    Digital Signature:
    Elliptic Curve Digital Signature Algorithm (ECDSA) 256 bit curve.	384 bit curve

    Key Exchange:
    Elliptic Curve Diffie-Hellman (ECDH)               256 bit curve.	384 bit curve

    Hashing:
    Secure Hash Algorithm (SHA)	                       SHA-256           SHA-384

 

* For Suite B compliance, the `ECDSA_P384#Microsoft Software Key Service Provider` as well as the `384` key size and `SHA384` as the hash algorithm may also be selected if the level of classification desired is Top Secret.  The settings that correspond with the required level of classification should be used. `ECDSA_P521` is also available as an option.  While the use of a 521 bit ECC curve may exceed the cryptographic requirements of Suite B, due to the non-standard key size, 521 is not part of the official Suite B specification.
 
**PKCS#1 v2.1** 


* XP clients and many non-windows systems [do not support this new signature format.][34]  This should be disabled if older clients need to be supported. [More Info][35]

* I would only recommend using it once you move to ECC algorithms for asymmetric encryption. ([source][36])

**Protect Microsoft CA DCOM ports**

The Windows Server 2003 CA does not enforce encryption on the ICertRequest or ICertAdmin DCOM interfaces by default. Normally, this setting is not required except in special operational scenarios and should not be enabled. Only Windows Server 2003 machines by default support DCOM encryption on these interfaces. For example, Windows XP clients will not by default enforce encryption on certificate request to a Windows Server 2003 CA. [source][37]



**CNG private key storage vs CSP storage**

If you enroll Certificate Template v3, the private key goes into the CNG private key storage on the client computer. If you enroll Certificate Template v2 or v1, the private key goes into CSP storage.   The certificates will be visible to all applications in both cases, but not their private keys - so most applications will show the certificate as available, but will not be able to sign or decrypt data with the associated private key unless they support CNG storage.

You cannot distinguish between CNG and CSP storages by using the Certificate MMC. If you want to see what storage a particular certificate is using, you must use `CERTUTIL -repairstore my *` (or `CERTUTIL -user -repairstore my *`) and take a look at the Provider field. If it is saying "... Key Storage Provider", than it is CNG while all other providers are CSP.

If you create the initial certificate request manually (Create Custom Request in MMC), you can select between "CNG Storage" and "Legacy Key" where legacy means CSP.
The following is my experience-based list of what does not support CNG - you cannot find an authoritative list anywhere, so this arrises from my investigations over time:

* EFS
     Not supported in Windows 2008/Vista, Supported in Windows 7/2008R2
* user encryption certificates
* VPN/WiFi Client (EAPTLS, PEAP Client)

* Windows 2008/7
      Not supported with user or computer certificate authentication
* TMG 2010
      server certificates on web listeners
* Outlook 2003
      user email certificates for signatures or encryption
* Kerberos
      Windows 2008/Vista- DC certificates
* System Center Operations Manager 2007 R2
* System Center Configuration Manager 2007 R2
* SQL Server 2008 R2-
* Forefront Identity Manager 2010 Certificate Management

[More information on CNG compatibility is listed here][38] (in Czech, though Chrome handles the auto-translation well)


**Decommissioning a PKI Tree**

If you deploy two PKI trees, with the intent to decommission the legacy tree at some point (where all old devices have become obsolete or upgraded) it may be a good idea to set the CRL Next Update field to Null.  This will (should?) prevent the continual polling for new CRLS to the clients.  The reasoning is that once the PKI is decommissioned, there will be no more administration, and no more revoked certs.  All remaining certs are simply left to expire.

[More information on PKI decommissioning available here][39]


  [1]: http://support.microsoft.com/default.aspx?scid=kb;EN-US;951721
  [2]: http://technet.microsoft.com/en-us/library/cc771348
  [3]: http://security.stackexchange.com/a/1772/396
  [4]: http://security.stackexchange.com/q/2268/396
  [5]: http://blogs.technet.com/b/askds/archive/2009/10/15/windows-server-2008-r2-capolicy-inf-syntax.aspx
  [6]: http://csrc.nist.gov/publications/nistpubs/800-78-3/sp800-78-3.pdf
  [7]: http://security.stackexchange.com/q/2558/396
  [8]: http://blogs.technet.com/b/pki/archive/2011/03/13/deployment-of-the-new-federal-common-policy-ca-root-certificate.aspx
  [9]: http://blogs.technet.com/b/pki/archive/2010/09/30/sha2-and-windows.aspx
  [10]: http://support.microsoft.com/kb/968730
  [11]: http://blogs.msdn.com/b/alejacma/archive/2009/01/23/sha-2-support-on-windows-xp.aspx
  [12]: http://blogs.msdn.com/b/alejacma/archive/2009/01/23/sha-2-support-on-windows-xp.aspx
  [13]: http://social.technet.microsoft.com/Forums/en-US/winserversecurity/thread/faa2c31c-c50f-4083-a641-eff41d7e1b39
  [14]: http://msdn.microsoft.com/en-us/library/aa386983%28v=vs.85%29
  [15]: http://security.stackexchange.com/q/15690/396
  [16]: http://technet.microsoft.com/en-us/library/cc784789%28v=WS.10%29.aspx
  [17]: http://social.technet.microsoft.com/wiki/contents/articles/4954.certificate-status-and-revocation-checking.aspx
  [18]: http://serverfault.com/q/394911/51457
  [19]: http://technet.microsoft.com/en-us/library/ee619723%28v=ws.10%29
  [20]: http://social.technet.microsoft.com/wiki/contents/articles/4954.certificate-status-and-revocation-checking.aspx
  [21]: http://www.microsoft.com/technet/prodtechnol/windowsserver2003/technologies/security/advcert.mspx
  [22]: http://blogs.technet.com/b/askds/archive/2009/06/25/implementing-an-ocsp-responder-part-ii-preparing-certificate-authorities.aspx
  [23]: http://technet.microsoft.com/en-us/library/cc784789%28v=WS.10%29.aspx
  [24]: http://security.stackexchange.com/q/15549/396
  [25]: http://security.stackexchange.com/q/15582/396
  [26]: http://technet.microsoft.com/en-us/library/cc787237%28v=ws.10%29.aspx
  [27]: http://technet.microsoft.com/en-us/library/cc782853%28v=ws.10%29.aspx
  [28]: http://social.technet.microsoft.com/wiki/contents/articles/4954.certificate-status-and-revocation-checking.aspx
  [29]: https://i.sstatic.net/Zg8uq.gif
  [30]: http://technet.microsoft.com/en-us/library/cc751157.aspx
  [31]: https://i.sstatic.net/dCnXz.jpg
  [32]: https://i.sstatic.net/kkZ0q.gif
  [33]: http://www.microsoft.com/en-us/download/details.aspx?id=14551
  [34]: http://social.technet.microsoft.com/Forums/en-US/winserversecurity/thread/561d0fcb-3879-4297-9ff0-d4d14fa01634
  [35]: http://technet.microsoft.com/en-us/library/cc753169.aspx
  [36]: http://social.technet.microsoft.com/Forums/en-US/winserversecurity/thread/faa2c31c-c50f-4083-a641-eff41d7e1b39
  [37]: http://technet.microsoft.com/en-us/library/cc784789%28v=WS.10%29.aspx
  [38]: http://www.sevecek.com/Lists/Posts/Post.aspx?ID=40
  [39]: http://blogs.technet.com/b/pki/archive/2012/01/27/steps-needed-to-decommission-an-old-certification-authority-without-affecting-previously-issued-certificates-and-then-switching-all-operations-to-a-new-certification-authority.aspx