Contents
Non-Exportable Private Key Export
Is it possible for Microsoft Windows to export a Certificate with its Private Key whose key had been marked as non-exportable? Yes. This also presents a security concern.
Background
Sometime in 2016/2017, I inherited administration of an Active Directory Federation Service (ADFS) server that kept crashing and took down Single Sign-On (SSO) services. Trying to replace it needed overcoming one major hurdle: the installed Certificates on the farm’s Windows servers were marked to NOT allow export of their Private Keys. This was a feature available in Microsoft Windows but, as I recently found out, not Linux. A backup of the .PFX files containing the Private Keys was not available. That left us in a difficult position about what to do with the failing server:
- Leave server as-is, periodically reboot it, and cause a momentary SSO outage each time
- Not a desirable option. Should server no longer boot up, SSO could cease to function entirely
- Replace server with a fresh installation
- Not an option. We had no copy of the Certificates’ Private Keys to install onto the new server with
- Migrate to a new server
- Feasible, but time-consuming option. Setting up brand-new ADFS servers and manually migrating hundreds of SSO configurations would have taken weeks or months
- Required cutover coordination with each SSO partner
- Could not be scripted or automated
- Feasible, but time-consuming option. Setting up brand-new ADFS servers and manually migrating hundreds of SSO configurations would have taken weeks or months
We ultimately chose to go with the migration. Fast-forward 5-6 years later, could there have been a better path? As it turned out — Yes! There is a way to export a Certificate with the Private Key whose key had been marked as not exportable. It could subsequently be copied onto and used by the new server.
A Certificate whose Private Key had been marked as not exportable CAN be exported with the key, contrary to popular beliefs. However, one should note that even though this article worked to resolve the few situations I faced, it may not apply to all certificate types or Windows versions. Your results may vary.
Before we proceed, please be sure to familiarize yourself with Certificate basics as this article assumes you have some degree of knowledge already.
Importance of Certificates
Certificates are essential in securing access, communication, and verifying authenticity. They are issued by Certificate Authorities entrusted with vouching for their authenticity, and there are two scopes that certificates can be requested from: Public and Private. There are different certificate types available, including web, code signing, and document signing. SSH “Certificates” (Keys) are NOT the same.
Certificate Owners manage the systems and applications where the certificate is used, and the Certificate Services Team manages the Certificate Authorities.
“The Certificate Services team is typically the group that has been given responsibility for managing relationships with public CAs and for the internal CAs. The Certificate Services team typically comprises one to three people. Though the team members have good knowledge and expertise about TLS server certificates, they do not have the resources or access required to directly manage certificates on the extensive number of systems where certificates are deployed. However, the Certificate Services team is often blamed when TLS certificate incidents, such as outages, occur.” (NIST.gov, Header 4.2)
Private Key Security
A Private Key is generated by the Certificate Owner with the Certificate Signing Request (CSR). Once signed by the Certificate Authority and properly paired, it holds the secret key to unlocking the Certificate and should not be shared. A threat actor could use a compromised Private Key for nefarious reasons, such as those described here (SSLstore) and here (GitGuardian).
Access to Private Keys must be limited to authorized, trained personnel. (NIST “5.1.10 Private Key Security”). Mission-critical systems should have their key stored in a HSM (Hardware Security Module), and Certificate Owners must be trained on proper procedures to keeping their private keys secure.
NIST recommends (“5.1.11 Rekey/Rotation“) that when the Certificate Owner/Administrator is terminated or re-assigned, the Certificates should be replaced with a new CSR/Private Key within 30 days of re-assignment or 5 days of termination unless automation was put in place. The previous certificate, once replaced, must be revoked. Furthermore, unless a valid business reason exists or an automated service is used that removes an administrator from manually accessing private keys, always generate a NEW CSR so a new Private Key is created.
Wildcard certificates, if compromised, pose an even greater threat (NSA).
All certificates should be inventoried. This ensures visibility for monitoring expiration dates, vulnerabilities, compliance and regulatory performance, and allows for more rapid response to large-scale incidents and attacks. (NIST “5.1.1 Inventory“)
Mark Private Key As “Not Exportable”?
Microsoft Windows has a feature to mark a Certificate’s Private Key as not exportable during installation or import.
For years, my PKI administration peers and I thought that was a secure way to implement the SSL Certificate, but while researching best practices for Private Key security and storage, I learned that was not the case. Contrary to widespread belief, it can STILL be exported — few administrators, myself included, knew that. This article will show you how.
What about Linux and Mac OS X? Do they have the option to mark a key as not exportable? No. In fact, certificates are stored as files on the filesystem and are accessible by anyone with root access. See SSLs.com for where the Private Keys are stored. Windows keeps them in the Registry and can also be accessed through the Certificates MMC Snap-in.
Because anyone with Administrator (or root) rights could export the Private Key — whether on Windows, Linux, or OS X, access to it must be limited to authorized, trained personnel.
How To Export A Non-Exportable Private Key
Now that we have covered what Certificates are and why Private Keys should be kept secret and secure, let us go over how to export a Certificate with its Private Key whose key was marked as “not exportable” in Windows. You may have a legitimate reason for doing so — like the 2016/2017 example I provided in the “Background” section above with regards to a failing Active Directory Federation Service (ADFS) server. Knowing how to do this back then would have saved weeks of unnecessary work that could have been spent on other projects instead!
Verify Private Key Existence
There are multiple ways to check whether a Private Key is connected to a certificate. From the Certificates MMC Snap-in, double-click on the Cert to view its General information:
PowerShell
Launch a PowerShell instance with Administrator rights. Substitute “*cert.yuenx.com*” with the name of the Certificate you want to check. It should return “HasPrivateKey” as “True”.
# Replace "*cert.yuenx.com*" with the name of the Cert you want to work on Get-ChildItem -Path Cert:\LocalMachine\My -Recurse | Where-Object {$_.Subject -like "*cert.yuenx.com*"} | Select-Object HasPrivateKey
Replace “Cert:\LocalMachine” with “Cert:\CurrentUser” to view the logged-on user’s certificates instead of the Computer’s.
You may view the cert’s other properties by changing “Select-Object HasPrivateKey” to “Select-Object *” or “Format-List *”:
# Replace "*cert.yuenx.com*" with the name of the Cert you want to work on Get-ChildItem -Path Cert:\LocalMachine\My -Recurse | Where-Object {$_.Subject -like "*cert.yuenx.com*"} | Format-List *
Confirm Export Options
Let us confirm that the Private Key is not exportable. MMC Snap-In > Right-click the certificate > All Tasks > Export:
Notice that “No, do not export the private key” is the only option available. Next, only the DER, Base-64, and PKCS #7 (P7B) export file formats are selectable and not PKCS #12 (PFX).
PowerShell
An error should occur when attempting to export: “Export-PfxCertificate: Cannot export non-exportable private key”.
# Replace "YuenX" with the password you want to protect the PFX export with $Passwd = ConvertTo-SecureString -String "YuenX" -Force -AsPlainText # Replace "*cert.yuenx.com*" with the name of the Cert you want to work on Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object {$_.Subject -like "*cert.yuenx.com*"} | Export-PfxCertificate -FilePath c:\temp\YuenX.pfx -Password $Passwd
Get Certificate’s Thumbprint
Obtain the Certificate’s thumbprint to ensure the right one will be worked on. MMC Snap-In > double-click the Certificate > Details tab > Thumbprint field:
PowerShell
A hexadecimal string representing the certificate’s Thumbprint should be output:
# Replace "*cert.yuenx.com*" with the name of the Cert you want to work on (Get-ChildItem -Path Cert:\LocalMachine\My -Recurse | Where-Object {$_.Subject -like "*cert.yuenx.com*"}).Thumbprint
Export Certificate with Private Key
This step will make a backup copy of the Certificate with its Private Key by exporting the appropriate piece of the Windows Registry. Administrator rights may be required.
Warning: The Windows Registry is an extremely important part of Windows and should NOT be edited without first performing a backup. In fact, trying to modify the Registry with the Registry Editor will result in the following warning:
“Using Registry Editor incorrectly can cause serious, system-wide problems that may require you to re-install Windows to correct them. Microsoft cannot guarantee that any problems resulting from the use of Registry Editor can be solved.”
Proceed at your own risk.
Launch the Registry Editor by using the search box on the taskbar and typing “regedit“. Locate the HKLM “Certificates” Registry key by navigating to: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\My\Certificates. Find the cert with the Thumbprint recorded in the previous step.
Right-click on the certificate you want to export a copy of and select “Export”. On the “Export Registry File” screen, you will see that the “Selected branch” has been selected. Have the file saved to a secure location.
PowerShell
There was an option to export the certificate as an XML file from the Registry (see Microsoft’s DevBlogs), but I was not able to find a simple way to import it back without lengthy coding. As such, this section is here just for informational purposes. If anyone knows how, please share in the Comments! Use the Windows Registry to make an export of the branch.
# Replace "*cert.yuenx.com*" with the name of the Cert you want to work on Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object {$_.Subject -like "*cert.yuenx.com*"} | Export-Clixml c:\temp\YuenX.reg
PowerShell export of the Registry as XML could not be re-imported. Use the Windows Registry to make a backup of the branch instead.
The exported XML file should look like the below (sensitive data has been removed). It cannot be double-clicked to re-import back into the Registry:
Import Certificate with Private Key
Copy the Windows Registry-exported file to the new system you want to install the Certificate with the Private Key onto. Double-click it to merge content into the target computer’s Registry. You should now find the Certificate installed on that system AND have the corresponding Private Key associated. Use the Certificate MMC Snap-In or PowerShell to confirm.
Although a Certificate and its Private Key can be installed onto a different Windows system with the backup method described in this article, the key remains not exportable. I have not been able to find a mechanism to change that.
Certificate copied to a different computer will continue to have its Private Key NOT be exportable on that system.
Bonus: Delete Certificate
One or more Certificates can easily be removed from a computer using PowerShell. Please proceed with extreme caution!
##################################### # WARNING! The below could accidentally be used to delete the WRONG or ALL # certificates if not done right! Always make a backup! ##################################### # Replace "*cert.yuenx.com*" with the name of the Cert you want to work on Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object {$_.Subject -like "*cert.yuenx.com*"} | Remove-Item
Final Thoughts
This article has shown how easy it was to copy a system’s Certificate and its Private Key onto another without knowing the key’s password (if any set) or having a backup. Just like Linux and Mac OS X, all one needed was to have Administrator (root) rights and make a backup of the Windows Registry. For that very reason, access to Private Keys must be limited to authorized, trained personnel — with strict controls and monitoring policies in place. Mission-critical systems should have their key stored in a HSM (Hardware Security Module), and Certificate Owners must be trained on proper procedures to keeping their private keys secure. Administrator or Root-level access should be limited and regularly monitored and audited.
Wildcard certificates pose an especially greater risk when compromised, should be limited in use despite their convenience and flexibility, and have even greater security controls in place.
One should note that even though this article worked to resolve the few situations I faced, it may not apply to all certificate types or Windows versions. Your results may vary.
With all that said, this article hopefully helped save you some time and headaches, reminded you of the importance of having backups of Certificates with their Private Keys, and had you examine how Private Key security may be managed at your organization. If you have not yet done so, start by reading through NIST’s TLS Server Certificate Management guidelines.
Credits:
– Featured Image by Pat Whelen via Unsplash
References
Related Posts
- OpenSSL Command Reference: Convert, Check, Verify, Extract
- FortiManager: CA-Signed Web Admin Certificate
- Google Chrome: Revoked Web Certificates