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.

A short introduction to Cryptographic Providers

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:

image

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.

Enumerate the list of providers

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:

  1. legacy CSP always specify Provider Type field.
  2. CNG providers usually use Key Storage Provider in their names.

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).

Dump CSP or KSP capabilities

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.

Enumerate keys in CSP and KSP

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:

  1. key container name (example: tq-07e1b2b4-eb66-4055-aeba-0fae6310f200)
  2. unique container name (example: 3b77025f895e02021ad09cc75d8b941d_c0f790f6-ac7a-4d83-add9-d6e26941ca7e)
  3. key algorithm (example: ECDH_P384)
  4. key algorithm group (example: ECDH)

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.

Relationships between certificate and key container

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.

Delete private keys in CSP and KSP

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.

Last Line

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!


Share this article:

Comments:


Post your comment:

Please, solve this little equation and enter result below. Captcha