Generate Private Keys on YubiKey and Use them on Windows

Up until I wrote this blog post, the tutorials and documentation I have come across regarding the use of Yubikey PIV certificates with Windows all involved having a complete set of private and public keys (generated outside of Yubikey) to be installed on Windows and imported into Yubikey for use. However, Yubikey also provides a more secure option: generating the private key on the Yubikey itself. The advantage of this method is that the private key never leaves the Yubikey, making it impossible for it to be leaked. But in such a case, we don't have a private key to import into Windows, and Windows is unaware of our corresponding digital certificate, so it won't consider our certificate as an available one for signing.

This article will explain how to generate a private key on the Yubikey and associate it with the certificate on Windows, to enable code signing on Windows. Although the purpose of this article is code signing, the association method described in the article also applies to other scenarios that require the use of private keys generated on the Yubikey.

Import the certificate whose private on Yubikey into Windows

In the usage of Hardware Security Modules (HSM), it is quite common to generate private keys on external hardware and delegate their signing. I believe that Windows Certificate Management definitely supports external private keys. Therefore, I searched the documentation of Yubico's HSM product, YubiHSM2, and found the following passage in its Code Signing documentation:

After importing the certificate to your personal store, use the certutil utility provided by Windows to associate the YubiHSM private key to the certificate.

1
> certutil -repairstore my <certificate hash>

Although this command can also be used for Yubikey, the problem is not that simple.

Make certutil recognize the certificate on Yubikey

To make this command work, you need to:

  1. Install YubiKey Smart Card Minidriver
  2. The management key of Yubikey PIV must be in "Protect with PIN" mode

Then try certutil -scinfo to see if it can recognize the certificate on Yubikey.

You may encounter an error like this:

There are two possible reasons for this:

  1. The management key of Yubikey PIV is not in "Protect with PIN" mode.
  2. An occasional bug, in which case re-plugging the Yubikey will fix it. It seems that this problem occurs when using the GPG function of Yubikey and then using the PIV function. I believe this is a bug.

Import the certificate and associate the private key

It seems that `certutil -scinfo` will automatically complete this step sometimes, I don't know why, so I suggest you check it first.

If certutil is able to recognize the certificate on Yubikey, you can import the certificate into Windows certificate store:

  • GUI: Open "Manage User Certificates", install to "Personal"
  • CLI: Install to certificate path cert:\currentuser\my

Then use certutil -v -user -csp "Microsoft Smart Card Key Storage Provider" -repairstore my <fingerprint> to associate the private key with the certificate.

  • The CSP is not "Microsoft Base Smart Card Crypto Provider", you may have been misinformed.
  • Your CSP should be the same as mine, if it's different, refer to the output of certutil -scinfo.

Now in the certificate manager, there should be a small key on the certificate, indicating that you have its private key.

Use Yubikey to sign code

First, choose the certificate to use:

1
$Cert = Get-ChildItem -Path 'cert:\currentuser\my' -CodeSigning | Out-GridView -PassThru

Select one from the pop-up dialog. Then:

1
Set-AuthenticodeSignature -Certificate $Cert -FilePath <file to sign>

The file to be signed can be a PS1 script or an executable (EXE) file.

Running signed PS1 scripts

The default execution policy of PowerShell does not allow running any scripts. To change it to only allow signed scripts, use the following command:

1
Set-ExecutionPolicy -ExecutionPolicy AllSigned -Scope CurrentUser

If you want to run scripts without getting warnings, you also need to copy the certificate to "Trusted Publishers".

References

  1. StackOverflow - Yubikey PIV "The smartcard cannot perform the requested operation."
  2. YubiHSM2 Docs - Creating a Code-Signing Certificate using the Key Storage Provider
  3. PowerShell Docs - about_Execution_Policies
  4. Microsoft Devblogs - How Can I Sign Windows PowerShell Scripts with an Enterprise Windows PKI? (Part 2 of 2)
  5. Yubico - Code Signing with the YubiKey on Windows

Generate Private Keys on YubiKey and Use them on Windows

https://blog.caomingjun.com/series/yubikey/piv-windows-repairstore/en/

Author

Cao Mingjun

Posted on

2023-08-08

Updated on

2023-08-08

Licensed under

Comments