Hello S-1-1-0,
Today I’m continuing my certutil tips and tricks post series. In this post, I will get an introduction into cryptographic service provider architecture and how certutil can list and query them.
Windows Cryptography relies on a cryptographic service provider (CSP) architecture when performing cryptographic operations. CSP is a program module that represents an abstraction between client application and functions that utilize private keys. Applications are not required to interact with private key material directly, implement cryptographic functions. They only interact with known CSPs that implement private key storage database and cryptographic functions and operations. Here is a simple diagram that shows the relationship between client application and CSP:
When certificate is installed into Windows Certificate Store, public certificate is installed in registry and private key is registered and installed in selected CSP. When necessary, application queries the CSP and asks CSP to do the job, say generate key, hash, encrypt or sign data and get results. Application has zero knowledge of what is happening behind.
Microsoft Windows can support multiple CSPs and allows developers to write their own CSPs. One common cases of custom providers are hardware key storages like smart cards and hardware security modules (HSM). Custom CSP implements cryptographic algorithms, operations and interaction with key storage on hardware devices. If application needs to access the certificate on a smart card, application just communicates with smart card CSP via unified interface and all the rest is done by CSP.
After releasing Windows Vista and Windows Server 2008, there is a brand new CSP subsystem called Cryptography Next Generation (CNG). CNG is was written from scratch and is not compatible with legacy CSP subsystem. CNG brings a lot of improvements to CryptoAPI, but the idea is still the same. Also, CNG ships a new class of CSPs called Key Storage Provider or KSP. In general, KSP and CSP are similar in terms of their purpose. CSP refers to legacy CryptoAPI 1.0 and KSP refers to CNG or CAPI2.
Microsoft ships a number of different providers with different capabilities. Custom providers may be installed. So, let’s start with basic operations.
we can use certutil -csplist to enumerate all registered providers (both, CSP and KSP):
PS C:\> certutil -csplist Provider Name: Athena ASECard Crypto CSP Provider Type: 1 - PROV_RSA_FULL Provider Name: Microsoft Base Cryptographic Provider v1.0 Provider Type: 1 - PROV_RSA_FULL Provider Name: Microsoft Base DSS and Diffie-Hellman Cryptographic Provider Provider Type: 13 - PROV_DSS_DH Provider Name: Microsoft Base DSS Cryptographic Provider Provider Type: 3 - PROV_DSS Provider Name: Microsoft Base Smart Card Crypto Provider Provider Type: 1 - PROV_RSA_FULL Provider Name: Microsoft DH SChannel Cryptographic Provider Provider Type: 18 - PROV_DH_SCHANNEL Provider Name: Microsoft Enhanced Cryptographic Provider v1.0 Provider Type: 1 - PROV_RSA_FULL Provider Name: Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider Provider Type: 13 - PROV_DSS_DH Provider Name: Microsoft Enhanced RSA and AES Cryptographic Provider Provider Type: 24 - PROV_RSA_AES Provider Name: Microsoft RSA SChannel Cryptographic Provider Provider Type: 12 - PROV_RSA_SCHANNEL Provider Name: Microsoft Strong Cryptographic Provider Provider Type: 1 - PROV_RSA_FULL Provider Name: Microsoft Software Key Storage Provider Provider Name: Athena Key Storage Provider Provider Name: Microsoft Passport Key Storage Provider Provider Name: Microsoft Platform Crypto Provider Microsoft Platform Crypto Provider: The device that is required by this cryptographic provider is not ready for use. Provider Name: Microsoft Smart Card Key Storage Provider CertUtil: -csplist command FAILED: 0x80090030 (-2146893776 NTE_DEVICE_NOT_READY) CertUtil: The device that is required by this cryptographic provider is not ready for use. PS C:\>
There are two ways to quickly say which provider is legacy CSP and which is CNG:
My current system has two custom providers, legacy CSP called “Athena ASECard Crypto CSP” and modern KSP called “Athena Key Storage Provider” which are used to access my Athena smart card. Providers may expose some capabilities in their names. For example, “Microsoft Enhanced RSA and AES Cryptographic Provider” name suggests, that this particular CSP implements AES algorithm operations (in fact, this CSP is the only built-in legacy CSP that implements AES). “Microsoft Platform Crypto Provider” provider suggests that it is intended to interact with Trusted Platform Module (TPM).
We can use certutil -csptest command to dump specific provider capabilities:
C:\> certutil -csp "Athena Key Storage Provider" -csptest
Provider Name: Athena Key Storage Provider
Name: Athena Key Storage Provider
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Impl Type: 11 (0xb)
NCRYPT_IMPL_HARDWARE_FLAG -- 1
NCRYPT_IMPL_SOFTWARE_FLAG -- 2
NCRYPT_IMPL_REMOVABLE_FLAG -- 8
Version: 65536 (0x10000)
Pass
Provider Aliases:
Athena ASECard Crypto CSP
Provider Module:
UM(1): aseKSP.dll
0(1): 10001, 1
0: KEY_STORAGE
Asymmetric Encryption Algorithms:
RSA
BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE -- 3
NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION -- 4
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
Secret Agreement Algorithms:
ECDH_P256
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDH_P384
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDH_P521
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
Signature Algorithms:
RSA
BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE -- 3
NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION -- 4
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDSA_P256
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDSA_P384
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDSA_P521
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
Asymmetric Algorithms:
RSA
BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE -- 3
NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION -- 4
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
NCryptCreatePersistedKey(Athena Key Storage Provider, RSA)
Algorithm Group: RSA
Algorithm Name: RSA
Length: 2048 (0x800)
Lengths:
dwMinLength = 1024 (0x400)
dwMaxLength = 4096 (0x1000)
dwIncrement = 512 (0x200)
dwDefaultLength = 2048 (0x800)
Block Length: 256 (0x100)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 0 (0x0)
Pass
ECDH_P256
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
NCryptCreatePersistedKey(Athena Key Storage Provider, ECDH_P256)
Algorithm Group: ECDH
Algorithm Name: ECDH_P256
Length: 256 (0x100)
Lengths:
dwMinLength = 256 (0x100)
dwMaxLength = 256 (0x100)
dwIncrement = 0 (0x0)
dwDefaultLength = 256 (0x100)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 0 (0x0)
Pass
ECDH_P384
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
NCryptCreatePersistedKey(Athena Key Storage Provider, ECDH_P384)
Algorithm Group: ECDH
Algorithm Name: ECDH_P384
Length: 384 (0x180)
Lengths:
dwMinLength = 384 (0x180)
dwMaxLength = 384 (0x180)
dwIncrement = 0 (0x0)
dwDefaultLength = 384 (0x180)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 0 (0x0)
Pass
ECDH_P521
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
NCryptCreatePersistedKey(Athena Key Storage Provider, ECDH_P521)
Algorithm Group: ECDH
Algorithm Name: ECDH_P521
Length: 521 (0x209)
Lengths:
dwMinLength = 521 (0x209)
dwMaxLength = 521 (0x209)
dwIncrement = 0 (0x0)
dwDefaultLength = 521 (0x209)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 0 (0x0)
Pass
ECDSA_P256
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
NCryptCreatePersistedKey(Athena Key Storage Provider, ECDSA_P256)
Algorithm Group: ECDSA
Algorithm Name: ECDSA_P256
Length: 256 (0x100)
Lengths:
dwMinLength = 256 (0x100)
dwMaxLength = 256 (0x100)
dwIncrement = 0 (0x0)
dwDefaultLength = 256 (0x100)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 0 (0x0)
Pass
ECDSA_P384
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
NCryptCreatePersistedKey(Athena Key Storage Provider, ECDSA_P384)
Algorithm Group: ECDSA
Algorithm Name: ECDSA_P384
Length: 384 (0x180)
Lengths:
dwMinLength = 384 (0x180)
dwMaxLength = 384 (0x180)
dwIncrement = 0 (0x0)
dwDefaultLength = 384 (0x180)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 0 (0x0)
Pass
ECDSA_P521
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
NCryptCreatePersistedKey(Athena Key Storage Provider, ECDSA_P521)
Algorithm Group: ECDSA
Algorithm Name: ECDSA_P521
Length: 521 (0x209)
Lengths:
dwMinLength = 521 (0x209)
dwMaxLength = 521 (0x209)
dwIncrement = 0 (0x0)
dwDefaultLength = 521 (0x209)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
HWND Handle:Binary:
0000 00 00 00 00 00 00 00 00 ........
Key Usage: 0 (0x0)
Pass
All Algorithms:
RSA
BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE -- 3
NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION -- 4
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDH_P256
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDH_P384
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDH_P521
BCRYPT_SECRET_AGREEMENT_INTERFACE -- 4
NCRYPT_SECRET_AGREEMENT_OPERATION -- 8
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDSA_P256
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDSA_P384
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
ECDSA_P521
BCRYPT_SIGNATURE_INTERFACE -- 5
NCRYPT_SIGNATURE_OPERATION -- 10 (16)
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
3DES
dwMinLength=192 dwMaxLength=192 dwIncrement=0
3DES_112
dwMinLength=128 dwMaxLength=128 dwIncrement=0
XTS-AES
dwMinLength=256 dwMaxLength=512 dwIncrement=128
DESX
dwMinLength=192 dwMaxLength=192 dwIncrement=0
DES
dwMinLength=64 dwMaxLength=64 dwIncrement=0
RC2
dwMinLength=16 dwMaxLength=128 dwIncrement=8
RC4
dwMinLength=8 dwMaxLength=512 dwIncrement=8
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
dwMinLength=256 dwMaxLength=512 dwIncrement=128
DESX
dwMinLength=192 dwMaxLength=192 dwIncrement=0
DES
dwMinLength=64 dwMaxLength=64 dwIncrement=0
RC2
dwMinLength=16 dwMaxLength=128 dwIncrement=8
RC4
dwMinLength=8 dwMaxLength=512 dwIncrement=8
SHA256
SHA384
SHA512
SHA1
MD5
MD4
MD2
AES-GMAC
AES-CMAC
RSA
DH
ECDH_P256
ECDH_P384
ECDH_P521
ECDH
RSA_SIGN
ECDSA_P256
ECDSA_P384
ECDSA_P521
ECDSA
DSA
RNG
FIPS186DSARNG
DUALECRNG
SP800_108_CTR_HMAC
SP800_56A_CONCAT
PBKDF2
CAPI_KDF
TLS1_1_KDF
TLS1_2_KDF
HKDF
CertUtil: -csptest command completed successfully.
C:\>
The output is quite verbose, but it exposes all supported symmetric and asymmetric algorithms, hash algorithms, key sizes, etc.. For example, this block shows RSA asymmetric key generation options:
Algorithm Name: RSA
Length: 2048 (0x800)
Lengths:
dwMinLength = 1024 (0x400)
dwMaxLength = 4096 (0x1000)
dwIncrement = 512 (0x200)
dwDefaultLength = 2048 (0x800)
Athena KSP supports RSA keys starting with 1024 bits and up to 4096 bits with 512 bit step and default key size is 2048.
Certutil can query provider database to list all keys stored within particular provider by running certutil -key command and specifying desired provider name:
C:\> certutil -csp "Microsoft Software Key Storage Provider" -key Microsoft Software Key Storage Provider: tq-07e1b2b4-eb66-4055-aeba-0fae6310f200 3b77025f895e02021ad09cc75d8b941d_c0f790f6-ac7a-4d83-add9-d6e26941ca7e ECDH_P384 ECDH tq-f81ae2fb-b235-4a44-bc3a-8698b3103549 610832fd5c5833e12471e0d4d28c0bc4_c0f790f6-ac7a-4d83-add9-d6e26941ca7e ECDH_P384 ECDH tq-04de85ef-2f1a-4396-9d70-a03fd8a48242 ca359a08fea20a03fdfd19f37c6027bf_c0f790f6-ac7a-4d83-add9-d6e26941ca7e ECDH_P384 ECDH CertUtil: -key command completed successfully. C:\>
The output shows three key containers (or keys) with the following information:
What is the difference between first two? Key container name is the name of key container which may contain one or more keys. Unique container name is key name within provider. Unique container name is used as a private key file name when software provider is used.
we can add -v switch in order to get more detailed output:
C:\> certutil -v -csp "Microsoft Software Key Storage Provider" -key
Microsoft Software Key Storage Provider:
tq-07e1b2b4-eb66-4055-aeba-0fae6310f200
3b77025f895e02021ad09cc75d8b941d_c0f790f6-ac7a-4d83-add9-d6e26941ca7e
AD(AT_NONE): b7680f1e88de194625f0d64b4b6bde9bea062a4d
AD(AT_KEYEXCHANGE): 1c68213f8ab0f04cef612ef48fe260ea669154f4
AD(AT_SIGNATURE): 40ffbfed123ac8deb0d6040b2e0c38cd8bbbea74
ECDH_P384
ECDH
Key Id Hash(rfc-sha1): 7092789a284e2f6490e5beab217a7c063936dcdc
Key Id Hash(sha1): a0e57d359dc667c2ec5705bcc9c22696267f16ef
Key Id Hash(bcrypt-sha1): ae761ac98deb8121d9d87a727b43eb3a8c42d061
Key Id Hash(bcrypt-sha256): c23b22c807e7c3629768ea017451f7fa82a0821ab29988bb192d1fff6a40e1d0
Container Public Key:
0000 04 81 48 02 a6 c4 7e 6b ae 9d 93 13 0c b1 84 bb
0010 d5 ba f4 97 37 4d 85 bb c3 ab ae 16 e7 19 58 10
0020 70 9c e1 41 71 a6 aa 83 f7 22 57 16 57 17 05 52
0030 25 93 ba be 2a 84 cc 3d a3 8e 7d 19 8f b5 2f f2
0040 70 7d 7a f9 88 77 0d 38 e2 b8 cd 72 c6 7e 98 df
0050 8d b5 eb a6 14 d6 68 52 73 29 7c 47 bf b3 3d 0b
0060 17
Cached Key Identifier: tq-07e1b2b4-eb66-4055-aeba-0fae6310f200: Found exact match
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
NCRYPT_ALLOW_SIGNING_FLAG -- 2
NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)
UI Policy = 0
(NCRYPT_UI_PROTECT_KEY_FLAG -- 1)
(NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG -- 2)
Version: 0
Export Policy = 0
(NCRYPT_ALLOW_EXPORT_FLAG -- 1)
(NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2)
(NCRYPT_ALLOW_ARCHIVING_FLAG -- 4)
(NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8)
Name: tq-07e1b2b4-eb66-4055-aeba-0fae6310f200
Algorithm Group: ECDH
Algorithm Name: ECDH_P384
Length: 384 (0x180)
Lengths:
dwMinLength = 384 (0x180)
dwMaxLength = 384 (0x180)
dwIncrement = 0 (0x0)
dwDefaultLength = 384 (0x180)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
(NCRYPT_ALLOW_EXPORT_FLAG -- 1)
(NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2)
(NCRYPT_ALLOW_ARCHIVING_FLAG -- 4)
(NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8)
Key Usage: 16777215 (0xffffff)
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
NCRYPT_ALLOW_SIGNING_FLAG -- 2
NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)
Security Descr: D:PAI(A;;0x80120089;;;NS)(A;;0xd01f01ff;;;BA)(A;;0xd01f01ff;;;SY)
Modified: 01.11.2016 15:51
Virtual Iso: 0 (0x0)
Per Boot Key: 0 (0x0)
Private key is NOT exportable
D:PAI(A;;0x80120089;;;NS)(A;;0xd01f01ff;;;BA)(A;;0xd01f01ff;;;SY)
Allow Write NT AUTHORITY\NETWORK SERVICE
Allow Write BUILTIN\Administrators
Allow Write NT AUTHORITY\SYSTEM
tq-f81ae2fb-b235-4a44-bc3a-8698b3103549
610832fd5c5833e12471e0d4d28c0bc4_c0f790f6-ac7a-4d83-add9-d6e26941ca7e
AD(AT_NONE): 75a883f9ace7bd02f9271e8efe3fd6b4548fe8e9
AD(AT_KEYEXCHANGE): 54ad855bc53968041a8433031362cfc88bc8cbe7
AD(AT_SIGNATURE): 89ad1b600b527adeccd2f2a27e1b565d054fdc90
ECDH_P384
ECDH
Key Id Hash(rfc-sha1): a1cf4cf92f7f38366b781074675b6cafaccf9c10
Key Id Hash(sha1): 9ceec12e97cb8e2f56cff51aba7865406c7a2f4e
Key Id Hash(bcrypt-sha1): ee79615101f64059e8b98d4ff6633b18b268bd08
Key Id Hash(bcrypt-sha256): fbea73a80c6941a87cbbf12bdd756c162e02efb1bbff0d2e64c6fe11e0c91f3d
Container Public Key:
0000 04 bc a9 d1 d4 07 58 50 e5 f5 0a 20 9f a7 ed d1
0010 12 cb e3 39 b0 3e 98 c9 aa c3 c6 ce 76 7f 6b 4f
0020 e1 01 aa 4b 9d c1 84 3d 8a ea 4e b6 e0 f3 c1 be
0030 bf c8 4c 90 1a 48 99 40 3b b2 0a cc a7 cf f7 a0
0040 c3 dc 90 93 74 ad a1 c5 3a 6b 8d 03 f6 69 b3 dd
0050 c5 49 de 23 b7 e8 3c 15 3d aa 8d 0a 77 0c 6f 55
0060 42
Cached Key Identifier: tq-f81ae2fb-b235-4a44-bc3a-8698b3103549: Found exact match
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
NCRYPT_ALLOW_SIGNING_FLAG -- 2
NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)
UI Policy = 0
(NCRYPT_UI_PROTECT_KEY_FLAG -- 1)
(NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG -- 2)
Version: 0
Export Policy = 0
(NCRYPT_ALLOW_EXPORT_FLAG -- 1)
(NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2)
(NCRYPT_ALLOW_ARCHIVING_FLAG -- 4)
(NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8)
Name: tq-f81ae2fb-b235-4a44-bc3a-8698b3103549
Algorithm Group: ECDH
Algorithm Name: ECDH_P384
Length: 384 (0x180)
Lengths:
dwMinLength = 384 (0x180)
dwMaxLength = 384 (0x180)
dwIncrement = 0 (0x0)
dwDefaultLength = 384 (0x180)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
(NCRYPT_ALLOW_EXPORT_FLAG -- 1)
(NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2)
(NCRYPT_ALLOW_ARCHIVING_FLAG -- 4)
(NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8)
Key Usage: 16777215 (0xffffff)
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
NCRYPT_ALLOW_SIGNING_FLAG -- 2
NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)
Security Descr: D:PAI(A;;0x80120089;;;NS)(A;;0xd01f01ff;;;BA)(A;;0xd01f01ff;;;SY)
Modified: 11.05.2018 20:09
Virtual Iso: 0 (0x0)
Per Boot Key: 0 (0x0)
Private key is NOT exportable
D:PAI(A;;0x80120089;;;NS)(A;;0xd01f01ff;;;BA)(A;;0xd01f01ff;;;SY)
Allow Write NT AUTHORITY\NETWORK SERVICE
Allow Write BUILTIN\Administrators
Allow Write NT AUTHORITY\SYSTEM
tq-04de85ef-2f1a-4396-9d70-a03fd8a48242
ca359a08fea20a03fdfd19f37c6027bf_c0f790f6-ac7a-4d83-add9-d6e26941ca7e
AD(AT_NONE): a9c052679273c3dba5f84327479d9c4d8a3403a5
AD(AT_KEYEXCHANGE): 928750413b6faf33c149ac49724d92d8f393c048
AD(AT_SIGNATURE): c3fbab9e2d67c92ff33dfba1e1e6e7bd5d69f010
ECDH_P384
ECDH
Key Id Hash(rfc-sha1): ba7e4b3a0c2d5ab2a953d4af54291e454a3313c3
Key Id Hash(sha1): 7ecec7e7a25fd55c68f6695e36f1670f76a72f61
Key Id Hash(bcrypt-sha1): cdebfc063e315a269e90fc0f5bdb9445102170ac
Key Id Hash(bcrypt-sha256): 89a52fb54b114af118f5294d61c068510de83671a251057524af5341eb602a2d
Container Public Key:
0000 04 70 82 b2 25 a8 3d 88 3b 28 0b ad 14 1e c4 99
0010 cb 05 92 a5 88 2f 9b 47 2b a1 82 12 b2 de 15 83
0020 f8 8d 50 b4 34 0e 4b 2d 4b 82 b8 d9 ac 9f 0e 2d
0030 3f 20 a5 e4 6e b2 90 66 b2 4b 62 ab 03 6b c0 d2
0040 5b 75 9c 3e e2 74 20 91 03 2c 39 a3 35 59 83 b2
0050 72 18 79 d0 f5 b2 0e 93 3e 14 e9 bf dd 7e 57 8a
0060 36
Cached Key Identifier: tq-04de85ef-2f1a-4396-9d70-a03fd8a48242: Found exact match
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
NCRYPT_ALLOW_SIGNING_FLAG -- 2
NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)
UI Policy = 0
(NCRYPT_UI_PROTECT_KEY_FLAG -- 1)
(NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG -- 2)
Version: 0
Export Policy = 0
(NCRYPT_ALLOW_EXPORT_FLAG -- 1)
(NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2)
(NCRYPT_ALLOW_ARCHIVING_FLAG -- 4)
(NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8)
Name: tq-04de85ef-2f1a-4396-9d70-a03fd8a48242
Algorithm Group: ECDH
Algorithm Name: ECDH_P384
Length: 384 (0x180)
Lengths:
dwMinLength = 384 (0x180)
dwMaxLength = 384 (0x180)
dwIncrement = 0 (0x0)
dwDefaultLength = 384 (0x180)
UI Policy:
dwVersion = 1 (0x1)
dwFlags = 0 (0x0)
pszCreationTitle = (null)
pszFriendlyName = (null)
pszDescription = (null)
Export Policy: 0 (0x0)
(NCRYPT_ALLOW_EXPORT_FLAG -- 1)
(NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2)
(NCRYPT_ALLOW_ARCHIVING_FLAG -- 4)
(NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8)
Key Usage: 16777215 (0xffffff)
NCRYPT_ALLOW_DECRYPT_FLAG -- 1
NCRYPT_ALLOW_SIGNING_FLAG -- 2
NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)
Security Descr: D:PAI(A;;0x80120089;;;NS)(A;;0xd01f01ff;;;BA)(A;;0xd01f01ff;;;SY)
Modified: 01.11.2018 18:18
Virtual Iso: 0 (0x0)
Per Boot Key: 0 (0x0)
Private key is NOT exportable
D:PAI(A;;0x80120089;;;NS)(A;;0xd01f01ff;;;BA)(A;;0xd01f01ff;;;SY)
Allow Write NT AUTHORITY\NETWORK SERVICE
Allow Write BUILTIN\Administrators
Allow Write NT AUTHORITY\SYSTEM
CertUtil: -key command completed successfully.
C:\>
Once again, with the -v switch we get very verbose output. This dump shows more details about each key. For example, it shows public key associated with the specified private key, file system permissions on the key and intended usages.
In previous section, we enumerated private keys within KSP, but what the certificate this key belongs to? We can query local certificate store and find matching certificate:
C:\> certutil -store my
my "Personal"
<...>
================ Certificate 3 ================
Serial Number: 1800000018899823eb0d33bb5e000000000018
Issuer: CN=*******
NotBefore: 05.11.2017 13:25
NotAfter: 05.11.2018 13:25
Subject: CN=*******
Non-root Certificate
Cert Hash(sha1): 697d819ccc5f3f00c2f12b89138c2c98f94837f7
Key Container = tq-f81ae2fb-b235-4a44-bc3a-8698b3103549
Unique container name: 610832fd5c5833e12471e0d4d28c0bc4_c0f790f6-ac7a-4d83-add9-d6e26941ca7e
Provider = Microsoft Software Key Storage Provider
Private key is NOT exportable
Encryption test passed
CertUtil: -store command completed successfully.
C:\>
And indeed, we saw selected (in bold) key container and unique container name in the certutil -key command's output:
tq-f81ae2fb-b235-4a44-bc3a-8698b3103549 610832fd5c5833e12471e0d4d28c0bc4_c0f790f6-ac7a-4d83-add9-d6e26941ca7e ECDH_P384 ECDH
this way we can bind the public certificate (which is stored in registry) to a corresponding private key.
Private key deletion may be very tricky. For example, many users and IT administrators think that by deleting the certificate from certificate store, the key is deleted as well. It is incorrect and this case was explained in one of my blog posts: The case of accidentally deleted user certificates. This means that when you need to delete the certificate and corresponding private key, you have to delete the key first. Then you can delete the certificate from certificate store.
We can use certutil to delete the private key material from device (file system or hardware device) with certutil -delkey command:
PS C:\> certutil -csp "Microsoft Software Key Storage Provider" -delkey tq-f81ae2fb-b235-4a44-bc3a-8698b3103549 tq-f81ae2fb-b235-4a44-bc3a-8698b3103549 CertUtil: -delkey command completed successfully. PS C:\>
I deleted the key container from previous example (the certificate is already expired, so it is not harmful in this case). The command doesn’t produce any useful output. However, if we query the certificate again, we will see the difference:
PS C:\> certutil -store my 1800000018899823eb0d33bb5e000000000018
my "Personal"
================ Certificate 3 ================
Serial Number: 1800000018899823eb0d33bb5e000000000018
Issuer: CN=********
NotBefore: 05.11.2017 13:25
NotAfter: 05.11.2018 13:25
Subject: CN=*********
Non-root Certificate
Cert Hash(sha1): 697d819ccc5f3f00c2f12b89138c2c98f94837f7
Key Container = tq-f81ae2fb-b235-4a44-bc3a-8698b3103549
Provider = Microsoft Software Key Storage Provider
Missing stored keyset
CertUtil: -store command completed successfully.
PS C:\>
Instead of “Encryption test passed” line we see another line: Missing stored keyset. We deleted the private key and certutil (and other tools as well) is unable to find the key and use it for any operation. Even though, the key icon is still present on certificate in certificate store, it is misleading, because the key is gone.
Today we explored the power of certutil in managing cryptographic providers and private keys. I’m a big fan of PowerShell, but PowerShell is nearly nowhere when the talk comes to cryptography. I’m still putting a lot of efforts to make PowerShell a little closer to certutil in these questions, but the road is very long. That’s all for today. Stay tuned for other PowerShell certutil stuff!
Thank you very much, for that material.
Thanks for the helpfull article.
Is there any possibility to import a public certificate (e.g. trusted third party, without having a private key) and store it's public key to a provider's container (e.g. based on a HSM)? So that the public key is not stored only within the certificate (at registery), but also at the provider's container (on HSM)?
You have written, that certificates are always stored at registery no matter what the provider is. And of course, public keys are stored within certificates. But public keys are also stored in CSP/KSP providers - as you shown with certutil and -key and -v flags.
So is the linkage from certificates to a public-key-only-container possible or is that something what windows doesn't support at all?
The goal would be a higher confidence when checking the PKI chain when e.g. connecting to the third party or verifying a signature (provided that windows look at the certificate's public key and checks it with the one stored on provider's container while doing PKI chain check)
Thank you
For public certificate import onto hardware devices (HSM, smart cards), you have to use software provided by HSM. I don't know ways to do this programmatically.
Thank you!
Fantastic explanation.!
User personal store. User certificate. Yet I cannot delete private key of expired certificate:
Administrator permissions are needed to use the selected options. Use an administrator command prompt to complete these tasks.
CertUtil: The requested operation requires elevation.
But ofcourse with evelvate cmd I get an error:
CertUtil: -delkey command FAILED: 0x80090016 (-2146893802 NTE_BAD_KEYSET)
CertUtil: Keyset does not exist
The key is listed correctly by
certutil -user -csp "Microsoft Software Key Storage Provider" -key
This is such a pain. It started in Windows 7 for me couple of weeks ago:
certutil Failed extract of third-party root list from auto update cab at: <http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab> with error: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. .
First I followed this tutorial, then tried to clean out the reg keys restart CryptSvc.
https://www.sysadmins.lv/blog-en/the-case-of-third-party-root-list-update-error.aspx
Still the error kept coming back. Then I downloaded that cab file extracted the STL from it and imported it following this guide:
https://knowledge.digicert.com/solution/SO13755.html
and finally worked. Keep deleting the stupid certificates will do NOTHING since it tries to redownload it and fail over and over again.
I couldn't even care less about using any certificate thingies it was just messing up my windows and needed to be fixed.
I know that Windows7 is out of date now but people will be using it for a good +20 years, I don't recall issues like this with Windows XP.
quick query how the certificate relates to the CSP function exposed? For example if my certificate has SHA256 hashing algorithm but the private key is stored in "Microsoft RSA SChannel Cryptographic Provider" which does not support SHA256 for hashing. How it will work?
FWIW, you can conveniently delete a certificate together with its private key in one go with PowerShell, using the "Cert:" drive, which exposes user and machine certificate stores as a pseudo-filesystem (stores are "directories" and certificates are "files" named after their thumbprints):
cd Cert:\CurrentUser\My
del .\<thumbprint> -DeleteKey
(Due to the way the Certificate namespace provider is implemented in PowerShell, the -DeleteKey parameter only works when the current location is inside the Cert: drive.)
@sebus The access rights (ACL) on the private key file may not grant Administrators the right to delete (happened for me today with a cert injected into an Azure virtual machine). You need to inspect and possibly change the permissions on the appropriate file.
For machine-level keys, the CNG Microsoft Software Key Storage Provider stores private keys as files in C:\ProgramData\Microsoft\Crypto\Keys. The CryptoAPI software CSPs do the same but in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys. In both cases file names match the "Unique container name" certificate property. For user-level keys, replace C:\ProgramData with %USERPROFILE%\AppData\Roaming.
Reference: https://docs.microsoft.com/en-us/windows/win32/seccng/key-storage-and-retrieval#key-directories-and-files
What I noticed is that the powershell cert: drive has CSP details but not for KSP keys. Do you think that will improve, it somewhat feeld KSP support is still laggard in many tools.
(ls Cert:\LocalMAchine\my).PrivateKEy.CspKeyContainerInfo
> drive has CSP details but not for KSP keys
it is known issue, PrivateKey property does not support KSP and this will never be fixed. Instead, you should use extension methods for X509Certificate2 class.
Hi, could you explain the difference between the KSP and the CertStore?
There are a lot of certificates stored in KSP, that I cannot see in the CertStore. But when I import a key-pair into the CertStore it seems that I can also see it in the KSP.
Is there a GUI that I can use to browse the KSP?
KSP and CSP are different key storage models. The fact that you can see keys in KSP that aren't visible in CSP means that these keys are stored in KSP. However, KSP has a bridge API NCryptTranslateHandle which allows to convert CSP handle into KSP handle. That is, KSP can access keys in both, KSP and CSP, while CSP can access keys only in CSP.
Hi,
i cannot delete key
PS C:\Users\Administrator> certutil.exe -v -csp "Microsoft Software Key Storage Provider" -delkey PFXEncryptionKeyImported
CertUtil: -delkey command FAILED: 0x80070005 (WIN32: 5 ERROR_ACCESS_DENIED)
CertUtil: Access is denied.
> CertUtil: Access is denied.
make sure if your PS console is running in elevated mode.
Hello,
is there a way to select or specify particular CSP (e.g. Microsoft Enhanced RSA and AES Cryptographic Provider) when creating pfx file?
or is it somehow associated how CSR is generated (e.g. openssl, mmc console or browser api?
Post your comment:
Comments: