Create a TPM backed certificate request (on windows)
Security in IT is around everywhere and within the recent years certificates have become the standard on connection security on the web but also on VPN connections like when using openvpn.
The most secure way to store a certificate - or rather the private key - is to generate it directly in the TPM and just derive a certificate signing request (CSR) from it. Using this way, the secret never leaves hardware security, not during creation, not during usage.
Creating the CSR
In order to create the signing request, you will need to use certreq and a configuration file.
The configuration ini file looks like this
The next step will be to request the certificate:
As a result you will get a file containing the request that you can pass on to the CA to get it signed.
The output will look somehow similar to this:
Importing the certificate
Having completed the certificate request and received the certificate itself, it's time to import it.
Nifty issues
Creating TPM based certificates has quite some sneaky issues, like it requires you to carefully select the algorithm, if you don't do this well, you are receiving errors like: The requested operation is not supported. 0x80090029 (-2146893783 NTE_NOT_SUPPORTED)
This indicates that the selected algorithm (ECDH_P384 in this example) is not supported by the crypto provider and the creation failed.
How to get information about supported algorithms?
For this you can use certutil and list all algorithms for a specific (or all) crypto store provider.
A shortened example output from my machine looks like this:
certutil -csp "Microsoft Platform Crypto Provider" -csptest
Provider Name: Microsoft Platform Crypto Provider
Name: Microsoft Platform Crypto Provider
Impl Type: 1 (0x1)
NCRYPT_IMPL_HARDWARE_FLAG -- 1
Version: 65536 (0x10000)
Pass
Provider Module:
UM(1): PCPKsp.dll
0(1): 10001, 0
0: KEY_STORAGE
Asymmetric Encryption Algorithms:
RSA
BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE -- 3
NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION -- 4
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
[...]
Pass
ECDH_P384
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCryptCreatePersistedKey(Microsoft Platform Crypto Provider, ECDH_P384)
Algorithm Group: ECDH
Algorithm Name: ECDH
ECCCurveName: nistP384
Length: 0 (0x0)
Lengths:
dwMinLength = 384 (0x180)
dwMaxLength = 384 (0x180)
dwIncrement = 0 (0x0)
dwDefaultLength = 384 (0x180)
Block Length: 96 (0x60)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 1 (0x1)
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
PCP_KEY_USAGE_POLICY: 65538 (0x10002)
NCRYPT_TPM12_PROVIDER -- 10000 (65536)
NCRYPT_PCP_ENCRYPTION_KEY -- 2
Pass
HMAC-SHA256
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
0x40 (64)
NCryptCreatePersistedKey(Microsoft Platform Crypto Provider, HMAC-SHA256)
Algorithm Name: HMAC-SHA256
Length: 0 (0x0)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 3 (0x3)
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
NCRYPT_ALLOW_SIGNING_FLAG -- 2
PCP_KEY_USAGE_POLICY: 65539 (0x10003)
NCRYPT_TPM12_PROVIDER -- 10000 (65536)
NCRYPT_PCP_SIGNATURE_KEY -- 1
NCRYPT_PCP_ENCRYPTION_KEY -- 2
NCRYPT_PCP_GENERIC_KEY -- 3
Pass
BCryptEnumAlgorithms:
Hash Algorithms:
SHA256
SHA384
SHA512
SHA1
MD5
MD4
MD2
AES-GMAC
AES-CMAC
Asymmetric Encryption Algorithms:
RSA
Secret Agreement Algorithms:
DH
ECDH_P256
ECDH_P384
ECDH_P521
ECDH
Signature Algorithms:
RSA_SIGN
ECDSA_P256
ECDSA_P384
ECDSA_P521
ECDSA
DSA
Cipher Algorithms:
AES
dwMinLength=128 dwMaxLength=256 dwIncrement=64
[...]
CHACHA20_POLY1305
dwMinLength=256 dwMaxLength=256 dwIncrement=0
RNG Algorithms:
RNG
FIPS186DSARNG
DUALECRNG
Asymmetric Algorithms:
RSA
DH
ECDH_P256
ECDH_P384
ECDH_P521
ECDH
RSA_SIGN
ECDSA_P256
ECDSA_P384
ECDSA_P521
ECDSA
DSA
All Algorithms:
AES
dwMinLength=128 dwMaxLength=256 dwIncrement=64
3DES
dwMinLength=192 dwMaxLength=192 dwIncrement=0
3DES_112
dwMinLength=128 dwMaxLength=128 dwIncrement=0
XTS-AES
[...]
DUALECRNG
SP800_108_CTR_HMAC
SP800_56A_CONCAT
PBKDF2
CAPI_KDF
TLS1_1_KDF
TLS1_2_KDF
HKDF
CertUtil: -csptest command completed successfully.
So, now you have some glimpse information about how to create TPM based certificate (requests) - time to get your hands dirty on it! :-)