Posts on this page:

Hello everyone!
This a good time for a new blog post! Today I want to share some thoughts on Key Recovery Agent (KRA) certificate management.

What is KRA and Key Archival

Let's refresh what private key archival is in AD CS context. Key Archival is the process of securily storing subscribers' (clients) private key in CA database for backup purposes should client loose access to private key. Key archival is primarily used to implement a centralized long-term backup process for encryption keys (email, EFS, document encryption).

The whole idea may not be apparent from the first look, but here is a strong reason: encryption keys are used to decrypt documents/files/emails even after their expiration, so you may need encryption key after its expiration. Expired certificates are not normally backed up as part of regular backup process or stored in long-term backup set. If certificate is expired, we normally renew it and delete old one. And you will be stuck if such encryption certificates and their keys are lost. This is why Microsoft implemented a separate encryption certificate backup process and store them in CA database. CAs are long-living entities, can live for decades and survive multiple migrations. And it can be easily backed up with regular backup process, because it will store a complete history of CA DB content, including historical one.

While it may look insecure, storing private keys in database is never a good idea, right? And this is where Key Recovery Agent (KRA) comes to a play. All private keys stored in CA database are encrypted with one or more KRA certificates. And even if you steal CA database and dump it, client private keys will be stored in encrypted blobs and CA/attacker has no access to KRA keys to decrypt client keys. Here is a timeline diagram that shows key archival process:

Key Archival flow

As you can see, private key material is protected at every stage: between client and CA (on a wire) it is protected with CA Exchange certificate. In CA DB, it is protected with one or more KRA certificates. And this process perfectly scales to any enterprise size, whether it is SMB, or large holding because of built-in automation using certificate templates.

Key recovery process is a bit different as it involves different entities:

Key Recovery flow

CA itself doesn't play any specific role, it acts as a secure storage. Instead, we involve two different entities: CA Manager, who has access to CA, CA database and retrieve encrypted blobs. CA Manager cannot decrypt these blobs, so we involve another entity, Key Recovery Agent. These MUST be different and highly trusted persons to avoid key archival misuse by a single person. So, CA Manager has access to CA DB, can retrieve encrypted blobs and that's pretty much all. KRA, on the other hand, can decrypt these blobs, but cannot retrieve them from CA DB. This is a clear responsibility separation. You cannot use single entity to compromise client keys.

What's wrong with KRA certificates?

While the whole process is pretty clear and understandable, there is a catch: KRA certs and keys MUST be available to decrypt the oldest encrypted client private key. And required KRA certificate MUST be easily identifiable over the time. Default recommendation is to use a pre-installed Key Recovery Agent certificate template to enroll for KRA certificates. Default validity is 2 years. Once it is expired, KRA has to enroll a new certificate and ask CA Administrator to replace expired KRA certs with new ones.

And here is the problem: KRA has to maintain the history of all its certificates and keys, including expired ones. When KRA certificate is replaced on a CA, previously encrypted client keys ARE NOT re-encrypted. So, in order to decrypt such key, KRA need its private key associated with certificate used to encrypt client's private key long ago. Assuming, CA lifetime of 20 years and default KRA cert validity of 2 years, you will end up with 10(!) different KRA certificates. And KRA is required to maintain them all. And this is where the process often fails. Comupters are changed/replaced/migrated much more often and it is enough to miss one KRA key backup process during PC replacement to make this KRA helpless. Of course, you can increase template validity to 5 years. It will reduce the number of keys from 10 to 4 per KRA. Still error-prone number.

I'm not familiar with latest official Microsoft recommendations as of today: the latest official whitepaper on Key Archival was released during Longhorn Beta 3, so I took an opportunity to think about my own solution.

Suggested Recommendation

Disclaimer: Suggested approach is provided by me. It may not comply with Microsoft recommendations or best practices or accepted by Microsoft Support. Provided recommendations are my own and gathered through my personal experience.

In order to make KRA certificate handling easier, less error-prone and keeping adequate security level, I propose to completely avoid CA-issued KRA certificates and instead use self-signed(!) ones with large validity. Yes, you read it right -- self-signed. Ultimately, KRA certificate will be valid throughout entire CA certificate validity.

KRA certificate validity scope is quite limited, it MUST be trusted only by CA and only at client private key encryption step (step 4.3 in first diagram). No other entity needs to trust KRA. And here we go: create a pair (at least) of long-living self-signed KRA certificates, configure them as trusted only CA server (install to Trusted Root CAs on CA itself only) and configure them as KRA certificates.

The only requirement here is to securely store KRA keys. Ideally, you would store them on smart cards, network1 HSMs, protected USB dongles. It is important to store them on a portable secure storage, so you can lock them in safe, or secure offline location. And never use only one smart card/storage. I would recommend to have at least a pair of KRA certs and physical storages to avoid single point of failure.

1 - I recommend to use network HSMs over PCIe ones, as netHSM provide high-availability (HA) configurations. PCIe HSMs may not provide redundancy.

With suggested approach we make key recovery process pretty transparent and much more reliable, because you don't have to maintain a potentially large history of KRA certificates, you maintain only one KRA key per agent. And you can align KRA certificate renewals with CA certificate renewals, which will allow KRA key rolling at reasonable periods, which will exceed 5yr period offered by CA-issued certs.

Suggested Recommendation Implementation

This section will provide steps to implement new approach, including self-signed certificate creation and CA configuration.

First step is to prepare a pair of smart cards, ensure that required driver/CSP/KSP is installed on your system. Consult with supported asymmetric key algorithms. Pick the strongest one. Often it will be RSA 4096, or ECDH_P384/ECDH_P521, though actual algorithm support will vary. In our use-case, I will use ECDH_P521.

Second step is to prepare a self-signed certificate creation script. I will use New-SelfSignedCertificate cmdlet:

$name = "Example Org KRA-1"
$ValidForYears = 20
New-SelfSignedCertificate -Subject "CN=$name, OU=Division of IT (DoIT), O=Example Org, C=LV" `
    -NotBefore ([datetime]::UtcNow) `
    -NotAfter ([datetime]::UtcNow.AddYears($ValidForYears)) `
    -Provider "Microsoft Software Key Storage Provider" `
    -HashAlgorithm "SHA512" `
    -KeyAlgorithm "ECDH_P251" `
    -KeyExportPolicy Exportable `
    -KeyUsageProperty All `
    -KeyUsage DataEncipherment `
    -CertStoreLocation Cert:\CurrentUser\My `
    -TextExtension @('2.5.29.37={text}1.3.6.1.4.1.311.21.6',"2.5.29.19={critical}{text}false") `
    -FriendlyName $name

This command uses Software KSP with exportable (in case if no smart card is used) ECDH_P521 key, SHA512 signature, 20 years validity, EKU is set to Key Recovery Agent and Basic Constraints extension is set explicitly as end-entity certificate and critical.

For smart card-based enrollment, the command would look like this:

$name = "Example Org KRA-1"
$ValidForYears = 20
New-SelfSignedCertificate -Subject "CN=$name, OU=Division of IT (DoIT), O=Example Org, C=LV" `
    -NotBefore ([datetime]::UtcNow) `
    -NotAfter ([datetime]::UtcNow.AddYears($ValidForYears)) `
    -Provider "Microsoft Smart Card Key Storage Provider" `
    -HashAlgorithm "SHA512" `
    -KeyAlgorithm "ECDH_P251" `
    -KeyUsage DataEncipherment `
    -CertStoreLocation Cert:\CurrentUser\My `
    -TextExtension @('2.5.29.37={text}1.3.6.1.4.1.311.21.6',"2.5.29.19={critical}{text}false") `
    -FriendlyName $name

The difference is: smart card KSP, no export flags.

Do not use TPM to store KRA keys.

Repeat these commands for "Example Org KRA-2" certificate. It should be identical to previous, only different subject name.

Third step: If you use software KSP, export all KRA certificates and delete private key from system after export. Copy PFX and passwords to removable media and put them to secure location (safe). Store PFX and password separately. After securing KRA private keys, export KRA certificates into .cer file (only public part, no private key) and copy them to CA server or transfer to CA administrator.

Fourth step: we need to establish a trust to KRA certs on CA server. Use certmgr.msc or certutil commands:

Certutil -addstore Root path\kra1.cer
Certutil -addstore Root path\kra2.cer
# next two commands will publish KRA certs to AD, configuration naming context. This is where CAs will look for available KRA certs
Certutil -dspublish -f path\kra1.cer KRA
Certutil -dspublish -f path\kra2.cer KRA

First two commands (certutil -addstore) must be invoked again after migrating CA to another server.

Fifth step: Use AD CS MMC (certmgr.msc) to add and configure KRA certificates. You may need until KRA certificates published in AD are replicated to all domain controllers.

  1. Open Certification Authority MMC snapin (certmgr.msc);
  2. Right-click CA node and select Properties in context menu;
  3. Switch to Recovery Agents tab;
  4. Press Add button and select new certificates;
  5. Add all required KRA certificates;
  6. Save changes and restart certificate services

Configured KRA certificates

Additional Reading

Here are two official Microsoft whitepaper related to key archival:
1. Key Archival and Management in Windows Server 2003
2. Key Archival and Management in Longhorn Beta 3

Happy Key Archival and Key Recovery!

Hello everyone!

Yesterday I pushed new PSPKI release with version number v3.3.0. New version is even more stable and even more powerful. More technical change list is moved to dedicated article: Release notes for PSPKI v3.3.0. In this (and, possibly next) blog post I would like to outline major changes/improvements to this release.

ADCS Database row presentation

I bet that ADCS database access is one of the most popular features people love in my module. And there are reasons: I put a lot of efforts to simplify access to CA database and provide flexible filter options. For example, get certificates that will expire in next 30 days:


Read more →

Hello S-1-1-0!

In previous post we gave an introduction into techniques to work with certificate revocation lists in PowerShell. We explored common steps to read CRL’s basic information, CRL extensions and revoked certificate collection. Today I will discuss about CRL handy shortcuts and signature validation.

Get CRL next publication date and number

In some environments, it is impossible to automatically copy CRLs from CA server to CRL distribution points or there is a scenario when PKI administrators run custom scripts to monitor CRL health status at CRL distribution points and update them if they are about to expire. For such purposes I maintain two shortcut methods to quickly identify required values.

CRL validity is determined by a NextUpdate field. If the current time passes that timestamp, the CRL is considered expired. To provide better validity handling, Microsoft use their own Next CRL Publish CRL extension. This extension contains a date/time value at which CA will issue new CRL. This value (when present) is always set prior to value in NextUpdate field to provide a time window to replicate newly published CRL across all distribution points prior existing CRLs expire. I have a good article on this subject: How ThisUpdate, NextUpdate and NextCRLPublish are calculated (v2). However, Next CRL Publish extension is presented in CRLs issued by Microsoft CAs and is absent in 3rd party CAs, as the result, next CRL publication date is determined solely by Next Update field. Moreover, there might be a case when CA is in the decommission process and issues its last CRL which is supposed to be valid infinitely.


Read more →

Hello everyone!

Today I would like to summarize techniques on working with X.509 certificate revocation lists (CRL) in PowerShell. There are a lot of examples in my weblog, but most of this information is provided as context-specific addition to work in a given article’s context. Before talking about the subject, I’d like to put few words about the reason of this blog post and why it is written in that way.

Motivation

As PowerShell evolves, it starts to cover more and new areas. And this process continues since PowerShell birth (in 2006). Systems administrators become more critical to script functionality. Previously, if something was not doable at all, we skipped that thing. With PowerShell we are able to do much more things. Maybe, not natively, maybe not in an elegant manner (say, through complex parsing), maybe very ugly, but we can do that right now. If community is interested in some area, they will develop a framework to make things easier and available to everyone.

One big area I’m interesting in is public key infrastructure, CryptoAPI, certificates and everything related to them. This happened several years ago (I recall it was in 2009) when I already was a passionate PowerShell enthusiast. Unfortunately, I realized that PowerShell has very-very basic support of certificate-related stuff. Mostly, this is due to poor support from underlying .NET platform. As the result, I attempted to start my big project to integrate cryptography into PowerShell through PS module and standalone scripts. Apparently, I was one of the first PS enthusiasts who started cryptography integration into PowerShell. I made huge work during these 7 years, went through tons of mistakes, bad choices, misunderstandings, trials and probes. It took 7 years and still continues. As of now, I have developed one of the best PowerShell module to work with PKI I’m aware of: PowerShell PKI. It is not just a module, it is a whole framework, which offers additional functionality through .NET-style objects and methods you can call from PS console. All this makes me confident in PowerShell PKI area.


Read more →

Hello everyone!

Some time ago I wrote a script that converts PEM file to CryptoAPI compatible format: How to convert PEM file to a CryptoAPI compatible format. The script involves some non-PowerShell commands (certutil) which associates private key with a certificate instance. I received several feedback comments about avoiding certutil in favor of native PowerShell/.NET managed code. In this post I want to show some code that eliminates certutil from the script.

Just to recall what we generally do when converting PEM to X509Certificate2/PFX:

  • Read the certificate information from PEM file and instantiate a X509Certificate2 object;
  • Read PKCS#1 or PKCS#8 private key;
  • Convert PKCS#1/PKCS#9 private key to CryptoAPI PRIVATEKEYBLOB;
  • Associate PRIVATEKYEBLOB with an X509Certificate2 instance.

Read more →