Search code examples
c++cryptographycryptoapiecdsacng

Why cert in certificate store doesn't have private key property


I tried to get EC private key from cert which in certificate store by CNG API. First, I call CertGetCertificateContextProperty() to get private key handle with CERT_KEY_CONTEXT_PROP_ID property, but it always return false. I'm sure that the cert has private key.

Code:

    wchar_t                 wMY_CERT_NAME[100];
    HCERTSTORE              hCertStore = NULL;
    PCCERT_CONTEXT          pSignerCert = NULL;
    NCRYPT_KEY_HANDLE       hKey = NULL;
    const int buffsize = 4999;
    DWORD len = buffsize;
    char buff[buffsize];

    // Open the certificate store.
    if (!(hCertStore = CertOpenStore(
        CERT_STORE_PROV_SYSTEM,
        0,
        NULL,
        CERT_SYSTEM_STORE_CURRENT_USER,
        CERT_STORE_NAME)))
    {
        MyHandleError(const_cast<LPTSTR>("The MY store could not be opened."));
    }

    swprintf(wMY_CERT_NAME, 100, L"%hs", MY_CERT_NAME);

    if (pSignerCert = CertFindCertificateInStore(
        hCertStore,
        MY_ENCODING_TYPE,
        0,
        CERT_FIND_SUBJECT_STR,
        wMY_CERT_NAME,
        NULL))
    {
        //continue
    }

    if (CertGetCertificateContextProperty(
        pSignerCert,
        CERT_KEY_CONTEXT_PROP_ID,
        buff,
        &len))
    {
        auto ckc = (CERT_KEY_CONTEXT *)buff;
        hKey = ckc->hNCryptKey;
    }
    else {
        wprintf(L"**** GetCertContextProperty failed.\n");
    }

Then, I tried to do the same step but read from a .pfx file like this page. It return true and get private key successfully. Why cert in certificate store doesn't have CERT_KEY_CONTEXT_PROP_ID property?


Solution

  • Certificates are signed public keys, they don't contain the private key. Most of the confusion stems from casual mis-use and conflation of terminology and concepts by people who don't understand cryptography properly.

    For example, .cert .cer .crt can contain keys and/or certificates. However, strictly a certificate is a signed public key.