Поделиться через


Функция CryptImportKey (wincrypt.h)

Важные этот API не рекомендуется. Новое и существующее программное обеспечение должно начинаться с API следующего поколения шифрования. Корпорация Майкрософт может удалить этот API в будущих выпусках.
 
Функция CryptImportKey передает криптографический ключ из ключа BLOB в поставщик служб шифрования (CSP). Эту функцию можно использовать для импорта ключа сеанса Schannel, регулярного ключа сеанса, открытого ключаили пары открытых и закрытых ключей. Для всех, кроме открытого ключа, ключ или пара ключей шифруется.

Синтаксис

BOOL CryptImportKey(
  [in]  HCRYPTPROV hProv,
  [in]  const BYTE *pbData,
  [in]  DWORD      dwDataLen,
  [in]  HCRYPTKEY  hPubKey,
  [in]  DWORD      dwFlags,
  [out] HCRYPTKEY  *phKey
);

Параметры

[in] hProv

Дескриптор CSP, полученный с помощью функции CryptAcquireContext.

[in] pbData

Массив BYTE, содержащий заголовок BLOB PUBLICKEYSTRUC, за которым следует зашифрованный ключ. Этот ключ BLOB создается функцией CryptExportKey либо в этом приложении, либо другим приложением, возможно, запущенным на другом компьютере.

[in] dwDataLen

Содержит длину в байтах ключа BLOB.

[in] hPubKey

Дескриптор криптографического ключа, расшифровывающий ключ, хранящийся в pbData. Этот ключ должен поступать из того же CSP, к которому относится hProv. Значение этого параметра отличается в зависимости от типа CSP и типа импортируемого ключевого BLOB-объекта:

  • Если ключ BLOB шифруется с помощью пары ключей обмена, например SIMPLEBLOB, этот параметр может быть дескриптором ключа обмена ключом.
  • Если ключ BLOB зашифрован с помощью ключа сеанса, например зашифрованный PRIVATEKEYBLOB, этот параметр содержит дескриптор этого ключа сеанса.
  • Если ключ BLOB-объект не зашифрован, например, PUBLICKEYBLOB, этот параметр не используется и должен быть нулем.
  • Если ключ BLOB-объекта зашифрован с помощью ключа сеанса в Schannel CSP, например зашифрованный OPAQUEKEYBLOB или любой другой поставщик OPAQUEKEYBLOB, этот параметр не используется и должен иметь значение нулю.
примечание некоторые поставщики служб csps могут изменить этот параметр в результате операции. Приложения, которые впоследствии используют этот ключ для других целей, должны вызывать функцию CryptDuplicateKey, чтобы создать дескриптор повторяющегося ключа. Когда приложение завершит работу с дескриптором, отпустите его, вызвав функцию CryptDeskkey.
 

[in] dwFlags

В настоящее время используется только в том случае, если пара открытых и закрытых ключей в виде PRIVATEKEYBLOB импортируется в CSP.

Этот параметр может быть одним из следующих значений.

Ценность Значение
CRYPT_EXPORTABLE
Импортируемый ключ в конечном итоге должен быть перераспрежден. Если этот флаг не используется, вызовы CryptExportKey с ошибкой дескриптора ключа.
CRYPT_OAEP
Этот флаг приводит к проверке форматирования PKCS #1 версии 2 с шифрованием RSA и расшифровкой при импорте SIMPLEBLOB.
CRYPT_NO_SALT
Значение без соли выделяется для 40-разрядного симметричного ключа. Дополнительные сведения см. в функциональных возможностяхзначений соли.
CRYPT_USER_PROTECTED
Если этот флаг задан, поставщик служб CSP уведомляет пользователя с помощью диалогового окна или другого метода при попытке выполнения определенных действий с помощью этого ключа. Точное поведение определяется типом CSP или типом CSP. Если контекст поставщика был получен с CRYPT_SILENT набором, использование этого флага приводит к сбою, а последняя ошибка имеет значение NTE_SILENT_CONTEXT.
CRYPT_IPSEC_HMAC_KEY
Позволяет импортировать ключ RC2 размером более 16 байт. Если этот флаг не задан, вызовы функции CryptImportKey с ключами RC2, превышающими 16 байт, завершаются ошибкой, а вызов GetLastError возвращает NTE_BAD_DATA.

[out] phKey

Указатель на значение HCRYPTKEY, которое получает дескриптор импортированного ключа. Завершив использование ключа, отпустите дескриптор, вызвав функцию CryptDekey.

Возвращаемое значение

Если функция выполнена успешно, функция возвращает ненулевое значение.

Если функция завершается ошибкой, она возвращает ноль. Для получения расширенных сведений об ошибке вызовите GetLastError.

Коды ошибок, предуставленные "NTE", создаются конкретным используемым поставщиком служб CSP. Ниже приведены некоторые возможные коды ошибок.

Возвращаемый код Описание
ERROR_BUSY
Некоторые поставщики служб csps задают эту ошибку, если закрытый ключ импортируется в контейнер, а другой поток или процесс использует этот ключ.
ERROR_INVALID_HANDLE
Один из параметров задает недопустимый дескриптор.
ERROR_INVALID_PARAMETER
Один из параметров содержит недопустимое значение. Чаще всего это недопустимый указатель.
NTE_BAD_ALGID
Импорт простого ключа BLOB не шифруется с ожидаемым алгоритмом обмена ключами.
NTE_BAD_DATA
Либо алгоритм, который работает с открытым ключом для импорта, не поддерживается этим поставщиком служб CSP, либо предпринята попытка импортировать ключ сеанса, зашифрованный с помощью одного из открытых ключей.
NTE_BAD_FLAGS
Указанный параметр dwFlags недействителен.
NTE_BAD_TYPE
Тип ключевого BLOB не поддерживается этим поставщиком служб CSP и, возможно, недействителен.
NTE_BAD_UID
Параметр hProv не содержит допустимый дескриптор контекста.
NTE_BAD_VER
Номер версии ключевого BLOB-объекта не соответствует версии CSP. Обычно это означает, что CSP необходимо обновить.

Замечания

При импорте ключа Hash-Based код проверки подлинности сообщений (HMAC) вызывающий объект должен определить импортированный ключ как тип PLAINTEXTKEYBLOB и задать соответствующий идентификатор алгоритма в поле aiKeyAlg заголовка PUBLICKEYSTRUC BLOB.

Функцию CryptImportKey можно использовать для импорта открытого ключа для симметричного алгоритма; однако рекомендуется использовать вместо этого функцию CryptGenKey. При импорте открытого ключа структура ключевого BLOB-объекта, передаваемого в параметре pbData, является PLAINTEXTKEYBLOB.

Вы можете использовать тип PLAINTEXTKEYBLOB с любым алгоритмом или типом сочетания ключей, поддерживаемым ВСП.

Пример импорта открытого ключа см. в разделе Пример программы C: импортоткрытого ключа.

В следующем примере показано, как задать поля заголовка.

keyBlob.header.bType = PLAINTEXTKEYBLOB;
keyBlob.header.bVersion = CUR_BLOB_VERSION;
keyBlob.header.reserved = 0;
// CALG_AES_128 is used as an example. You would set this to the 
// algorithm id that corresponds to the one used by the key.
keyBlob.header.aiKeyAlg = CALG_AES_128;

Длина ключа указывается в keyBlob.keyLength, за которой следует фактические данные ключа.

Примечание алгоритмы HMAC не имеют собственных идентификаторов алгоритмов; вместо этого используйте CALG_RC2. CRYPT_IPSEC_HMAC_KEY позволяет импортировать ключи RC2 дольше 16 байт.
 
Для любого из стандартных ключей шифрования данных (DES), использующих PLAINTEXTKEYBLOB, можно импортировать только полный размер ключа, включая бит четности.

Поддерживаются следующие ключевые размеры.

Алгоритм Поддерживаемый размер ключа
CALG_DES 64 бита
CALG_3DES_112 128 бит
CALG_3DES 192 бита
 

Примеры

В следующем примере показано, как импортировать ключ из ключа BLOB. Полный пример этой функции см. в разделе Пример программы C: подписывание хэша и проверка хэш-подписи. Дополнительные сведения о коде, использующего эту функцию, см. в примере программы C: расшифровка файла.

#include <windows.h>
#include <stdio.h>
#include <Wincrypt.h>

BOOL ImportKey(HCRYPTPROV hProv, LPBYTE pbKeyBlob, DWORD dwBlobLen)
{
    HCRYPTKEY hPubKey;

    //---------------------------------------------------------------
    // This code assumes that a cryptographic provider (hProv) 
    // has been acquired and that a key BLOB (pbKeyBlob) that is 
    // dwBlobLen bytes long has been acquired. 

    //---------------------------------------------------------------
    // Get the public key of the user who created the digital 
    // signature and import it into the CSP by using CryptImportKey. 
    // The key to be imported is in the buffer pbKeyBlob that is  
    // dwBlobLen bytes long. This function returns a handle to the 
    // public key in hPubKey.

    if(CryptImportKey(
        hProv,
        pbKeyBlob,
        dwBlobLen,
        0,
        0,
        &hPubKey))
    {
        printf("The key has been imported.\n");
    }
    else
    {
        printf("Public key import failed.\n");
        return FALSE;
    }

    //---------------------------------------------------------------
    // Insert code that uses the imported public key here.
    //---------------------------------------------------------------

    //---------------------------------------------------------------
    // When you have finished using the key, you must release it.
    if(CryptDestroyKey(hPubKey))
    {
        printf("The public key has been released.");
    }
    else
    {
        printf("The public key has not been released.");
        return FALSE;
    }

    return TRUE;
}

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows XP [только классические приложения]
минимальный поддерживаемый сервер Windows Server 2003 [только классические приложения]
целевая платформа Виндоус
заголовка wincrypt.h
библиотеки Advapi32.lib
DLL Advapi32.dll

См. также

CryptAcquireContext

CryptDeskkey

CryptExportKey

функции создания ключей и функций Exchange