Почему у сертификата в хранилище сертификатов нет свойства закрытого ключа

Я попытался получить закрытый ключ EC из сертификата, который находится в хранилище сертификатов с помощью CNG API. Сначала я вызываю CertGetCertificateContextProperty(), чтобы получить дескриптор закрытого ключа со свойством CERT_KEY_CONTEXT_PROP_ID, но он всегда возвращает false. Я уверен, что у сертификата есть закрытый ключ.

Код:

    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");
    }

Затем я попытался сделать тот же шаг, но прочитал из файла .pfx, например эта страница. Он возвращает истину и успешно получает закрытый ключ. Почему сертификат в хранилище сертификатов не имеет свойства CERT_KEY_CONTEXT_PROP_ID?


person Assam    schedule 08.04.2020    source источник


Ответы (2)


Сертификаты - это подписанные открытые ключи, они не содержат закрытого ключа. Большая часть путаницы возникает из-за случайного неправильного использования и смешения терминологии и понятий людьми, которые не понимают криптографию должным образом.

Например, .cert .cer .crt может содержать ключи и / или сертификаты. Однако строго certificate - это подписанный открытый ключ.

person Woodstock    schedule 08.04.2020
comment
Привет, Вудсток, я проверил сертификат в магазине сертификатов. Появляется сообщение У вас есть закрытый ключ, соответствующий этому сертификату. Это не значит иметь закрытый ключ? Я использовал эти сертификаты, чтобы подписывать, расшифровывать файлы и нормально работать. Сертификат в магазине импортируется из файла .pfx. - person Assam; 08.04.2020
comment
Сертификаты нельзя использовать для подписи по определению. Соответствующий ключ находится вне сертификата. Технически неправильно говорить, что данные подписаны сертификатом, но это достаточно близко. Цифровые подписи создаются с использованием закрытого ключа. Сертификат содержит соответствующий открытый ключ, который можно использовать для проверки действительности подписи. - person Woodstock; 08.04.2020
comment
Понятно. Итак .. Вы знаете, как экспортировать закрытый ключ EC? Я успешно экспортировал закрытый ключ RSA, но не смог получить закрытый ключ EC. Подробное описание: здесь - person Assam; 08.04.2020
comment
Как вы сгенерировали ключ в этом примере, запрещает экспорт (с первого взгляда), вам нужно воссоздать ключ, разрешающий экспорт через упаковку. Закрытый ключ ECC - это просто 256-битное число, это не специальная структура данных, аналогично закрытый ключ RSA - это просто число, которое используется в качестве показателя степени. Нет особой причины, по которой RSA будет экспортировать, а ECC - нет / - person Woodstock; 08.04.2020
comment
хм ... Я не понимаю, почему этот пример запрещает экспорт. Не могли бы вы поделиться дополнительной информацией? и не могли бы вы дать мне несколько советов по воссозданию ключа для разрешения экспорта? - person Assam; 08.04.2020

По моему опыту, если пользовательский интерфейс сертификата сообщает, что у вас есть закрытый ключ, вы должны иметь возможность открыть ключ и использовать его. Это не считается экспортом. Вы пробовали CryptAcquireCertificatePrivateKey?

Как пишет Вудсток, закрытый ключ не является частью сертификата и даже не хранится вместе с сертификатом. Закрытые ключи хранятся в другом месте. Однако открытый ключ является частью сертификата, и код может сканировать локальную библиотеку ключей в поисках закрытого ключа, который имеет тот же алгоритм, что и сертификат, и соответствует открытому ключу в сертификате. .

Одна морщина - флаг "сильной защиты ключа". Если он установлен, при любой попытке получить закрытый ключ будет всплывать подсказка. Вот почему CryptAcquireCertificatePrivateKey имеет параметр дескриптора родительского окна, а также флаг "молчания". Насколько мне известно, нет никакого способа удалить его, кроме воссоздания ключа.

person Seva Alekseyev    schedule 14.05.2020