The problem is : Nothing prevents the user to copy the certficate/key on a different hardware device and use it from a different hardware device...

Is it possible to generate a really unique certificate taking hardware in consideration ?

  • If you want uncopyable/unexportable private-keys you may have to use special hardware to help you: Wiki: HSM. Feb 8, 2018 at 18:50
  • @StackzOfZtuff HSM for VPN client? Seriously? $50k for just client keys? I would suggest to use TPM (Trusted Platform Module) which is built on many modern boards.
    – Crypt32
    Feb 8, 2018 at 19:02
  • @Crypt32: Yeah. TPM is good. Or another "Secure Element" of some kind. Anything hardware-y. Cheapo HSMs maybe: -> shop.nitrokey.com/de_DE/shop/product/nitrokey-hsm-7 Feb 8, 2018 at 19:10
  • This sounds more like Smart Card, not HSM.
    – Crypt32
    Feb 8, 2018 at 19:15
  • If we are talking about X509, you can tie one of the identifiers to a known hardware property, like mac address. This way when certificate is moved it will no longer match. However, this is trivially easy to work around for an attacker and will only deter casual users. Feb 21, 2018 at 14:05

1 Answer 1


You can generate a virtual smart card on a Trusted Platform Module (TPM). A TPM is like a Hardware Security Module (HSM), except that a TPM is physically attached to a computer's motherboard and thus isn't portable.

Lots of motherboards have TPMs on them, it's just that a lot of people don't know it and therefore don't often use their TPM. The main advantage of a TPM is probably its lower cost, relative to HSMs. A TPM is even more affordable than smart cards, which have to be provisioned to every user and replaced whenever lost. Another advantage of a TPM, relative to smart cards, is that its non-portability makes it unlikely to be misplaced.

About VSC's: A Virtual Smart Card (VSC) lives on the TPM and stores the private key of a certificate. The VSC is capable of being protected by a PIN, and the PIN can be set to a minimum level of complexity depending on how you created the VSC.

Here are some instructions to get you started (note: Windows is required):

Check to see if your TPM is active:

  • Click on the Windows icon, then type the following command, right-click on the icon and execute it as an administrator:

  • Look at the value for Status. The TPM is active if it says "The TPM is ready for use."

  • If the TPM is not active, you should look for it in your BIOS and enable it if it exists.

  • If the TPM does not exist on your system then stop here, as subsequent steps do not apply.

How to Create a Virtual Smart Card on the TPM:

  • Screencast video here: https://youtu.be/MSw59AKvwSo

  • You will need the following pieces of information before creating your Virtual Smart Card:

    • Name: The name of the Virtual Smart Card, to distinguish it from any others on the same TPM (there can be up to 10).
    • PIN: A password. The password must conform to these complexity rules:
      • At least 10 characters
      • Mix of uppercase and lowercase
      • Must include special characters
    • AdminKey: This is like a password, except that the AdminKey must be in hex format, and the number of characters in the hex format must be 48. This equates to 24 plain text characters. A text-to-hex conversion utility may be useful .
      • Example of a hex key converted from plain text into Hex:
        • Plain text (24 characters): abcdefghijklmnopqrstuvwx
        • Hex (48 characters with spaces omitted): 6162636465666768696a6b6c6d6e6f707172737475767778
      • Choose your own 24-character admin key (DON'T use the example above), convert that 24-characters from plain text into a 48-character hex value, then keep your 48-character hex value ready for the following steps.
    • PUK: A PIN unlock key, i.e. another password. The PUK is needed whenever it is necessary to release a lock caused by inputting an incorrect password too many times.
  • Open a command line terminal in administrator mode.

  • Edit the following command, replacing "MyVSCName" with the name you chose above for the virtual smart card. Then copy and paste the edited command into the terminal:

    tpmvscmgr.exe create /name "MyVSCName" /pin PROMPT /pinpolicy minlen 10 uppercase REQUIRED lowercase REQUIRED digits REQUIRED specialchars REQUIRED /AdminKey PROMPT /puk PROMPT /attestation AIK_AND_CERT /generate

  • You will see a series of questions asking for your PIN, your admin key, and your PUK. Paste in the corresponding values that you have prepared above.

  • Your Virtual Smart Card should now exist on the TPM. You can verify its existence by listing all Virtual Smart Cards in the TPM, using the following command:

    wmic path win32_PnPEntity where "DeviceID like '%smartcardreader%'" get DeviceID,Name,Status

How to Destroy a Virtual Smart Card on the TPM:

  • Open a command line terminal in administrator mode.

  • List the Virtual Smart Cards in the TPM:

    wmic path win32_PnPEntity where "DeviceID like '%smartcardreader%'" get DeviceID,Name,Status

  • Take note of the value under "DeviceID" for the Virtual Smart Card to be deleted.

  • Edit and then execute the following command, replacing "MyDeviceID" with the actual DeviceID of the virtual smart card that you want to delete:

     tpmvscmgr destroy /instance "MyDeviceID"

Generate a certificate signing request that is signed by the private key within your TPM:

  • Open a text editor such as Notepad or Sublime Text.

  • Copy the following code and paste it into your text editor:

     Subject = "CN=[user's e-mail address or server's domain name],O=[Organisation],L=[Locality],ST=[State],C=[Country]"
     Keylength = 2048
     Exportable = FALSE
     UserProtected = TRUE
     MachineKeySet = FALSE
     ProviderName = "Microsoft Base Smart Card Crypto Provider"
     ProviderType = 1
     RequestType = PKCS10
     KeyUsage = 0x80
  • For the Subject line, replace the values in brackets with your own values, to match your circumstances. (You should omit the bracket characters themselves.)

  • Save the text file with a ".inf" file extension. For example:

  • Open a command line terminal in administrator mode.

  • From the command line terminal, change the directory (cd) to where you saved the ".inf" file above.

  • Now generate a Certificate Signing Request (CSR). Copy and paste the following code into the command line terminal:

     certreq -new -f TPM-cert-template.inf TPM-cert.csr
  • You should see a pop-up dialog from Windows which asks you to select the Virtual Smart Card that will generate your certificate signing request. Note that a TPM can store multiple Virtual Smart Cards, but in this pop-up dialog you may only see just one of them (if more than one exist). Make sure that you expand the list before selecting a virtual smart card, and thereafter you'll see clearly to select the specific Virtual Smart Card that should generate the signing request.

  • After selecting the virtual smart card, you'll need to input the PIN.

  • If you input the correct PIN, then a new file should be generated in the same directory:


Prepare your server to authenticate your key pairs:

  • You should now have a CSR that you will need to have signed by a certificate authority. Once the certificate authority has signed your CSR, it should send you back a certificate in either PEM or DER format.

  • If you don't have a certificate authority, you can create your own, but creating your own will mean that every client that uses your signed certificate will need to recognize the certificate authority that you created. To do this, you'll need the certificate authority to send you not only the signed certificate that you were initially seeking, but also the certificate authority's own root certificate.

    • If you are using your own private certificate authority, then you'll need to get every server that you authenticate against to recognize your private certificate authority. This will involve installing the root certificate of your private certificate authority on every server that you authenticate against.
  • Once you have the signed certificate from your certificate authority, you'll need to install the signed certificate on every server or VPN that you need to authenticate against.

Prepare your server to authenticate your user:

  • To get your client software to authenticate with the server or VPN where you installed your certificate, you'll now need software which can leverage the APIs that connect to your TPM. For this there is a utility for Windows called PuTTYWinCrypt, which is a fork of the popular PuTTY program. It enables you to connect to a server over SSH or SCP. The source code for PuTTYWinCrypt is available on GitHub at the time of this writing. The author of this software has also written a fork of related software often combined with PuTTYWinCrypt known as PageantWinCrypt, which runs in the background keeping the keys in memory.

  • Now that your server recognizes your certificate authority, you should prepare it to recognize the public key of the specific user who will be connecting. The public key needs to be in OpenSSH format, meaning that the entire text of the key is written out on a single line. You probably won't be able to convert your public key from PEM into OpenSSH format, because such a conversion requires that you have access to the private key. In your case, the private key is confined to your TPM and is therefore not directly accessible. The following steps will help you obtain your public key in OpenSSH without direct access to its corresponding private key.

  • Download and execute PageantWinCrypt. This software is a patched version of the popular program Pageant, which stores keys in memory and runs in the background as an icon in the Windows system tray. Once you double-click on the executable file, not much will be obvious except that there is now an icon for PageantWinCrypt in your system tray, indicating that PageantWinCrypt is running. Note that the icon for PageantWinCrypt is labeled as "Pageant," not "PageantWinCrypt," so you'll need to be sure that you're specifically running PageantWinCrypt in order for this to work.

  • Click on the Windows icon in the lower-left corner of the screen, type the following, right click on its icon (which should appear as you type), and select "Run as administrator":

  • A window should pop up, showing a list of certificates with expandable folder icons. You need to find and expand the specific folder where you installed your signed certificate. Within that expanded folder, left-click on the subfolder called "Certificates." Left-click on your specific certificate, to select it. Then go to the "Action" menu item, and select "Copy" from the dropdown. Your certificate is now in memory. You need to import it from memory, into PageantWinCrypt.

  • Right-click on the icon for PageantWinCrypt in your system tray, and select "Add Certificate." You may get a pop-up dialog saying "Select a Certificate." Click OK. Your key should now be in PageantWinCrypt. You can confirm this by right-clicking again on the Pageant icon and selecting "View Keys." There should be a line entry which corresponds to your key. It may not be obvious but you can copy that line entry into memory simply by double-clicking on it. Paste the copied line into a text editor, such as Notepad.

  • Observe the pasted text. It should all be on a single line. But there are two parts to this long line, and you'll need to separate the parts into two lines. The second part begins with the following, and continues all the way until the end of the line:

  • In your text editor, click the mouse to just before cert:// and press Enter a few times on your keyboard. There should now be two lines of text, with the second line beginning with cert:\\. Note the following:

    • The first line is your public key in OpenSSH format. If your server is on Linux, you'll need to add your OpenSSH-formatted public key to your server's authorized_keys file.

      • To find the location of your authorized_keys file, connect to your Linux server via SSH and input the following command. A search will occur, and then output the path to the authorized_keys file:

          sudo find / -name "authorized_keys" 2>/dev/null
      • Take note of the path to authorized_keys from the step above. Now you need to edit authorized_keys and paste in your OpenSSH-formatted public key. Execute the following command, replacing the text "[path-to-authorized-keys]" with the path in your case (omit the brackets from the example below):

          sudo nano "[path-to-authorized-keys]"
      • The Linux-based text editor nano will now open, displaying the contents of authorized_keys. Scroll to the bottom and add a new line, by pasting the OpenSSH-formatted public key that you already copied. After pasting, simply save the file and exit.

    • Your Linux server is now configured to authenticate your TPM-enabled SSH connection. Now, in Windows, you need to set up your TPM-compatible software, in order to facilitate the SSH connection on your side.

    • In the text editor, the second line of text that you pasted earlier is the authentication string. It corresponds to the private key on your TPM. This line, beginning with cert:\\, is what you need to paste into PuTTYWinCrypt as described below.

Use TPM-accessible software to log in:

  • Open PuTTYWinCrypt. Under the Category Connection : SSH : Auth, in the space that is labeled "Private key file for authentication," paste the text beginning with cert:\\. Normally, without using a TPM, in this space you would paste in the path to your private key that lives on your hard drive. But in the process that you're following here, the private key is safely stored in your TPM, which by comparison is much more secure. Once you paste this text (beginning with cert:\\) in that space, you'll be able to authenticate with the same server that you installed the public key. To persist your changes, remember to save your connection; in PuTTYWinCrypt, under the Category Session, click on the Save button.

  • In PuTTYWinCrypt, try connecting now via SSH. If you configured everything properly, you should get a pop-up from the Virtual Smart Card on your TPM, asking for your PIN. Input the PIN. If the PIN is accurate, the SSH connection should continue and connect as expected.

  • You're done! You just connected to your server over SSH with a private key that is safely stored on your TPM.

The above information was inspired by, and partially obtained from, an informative blog post by Chris van Marle.

One final note: researchers at IBM are currently developing what they call Virtual TPMs, which will make it possible to migrate TPM functionality from one cloud host to another.

  • I would strongly recommend using PuTTY-CAC instead of PuTTYWinCrypt, as the latter is unmaintained and already several releases behind. Despite the name, PuTTY-CAC can use any certificate available through CAPI (or through PKCS#11) and is not limited to military smartcards.
    – grawity
    Dec 22, 2020 at 17:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .