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

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

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

Синтаксис

BOOL CryptExportKey(
  [in]      HCRYPTKEY hKey,
  [in]      HCRYPTKEY hExpKey,
  [in]      DWORD     dwBlobType,
  [in]      DWORD     dwFlags,
  [out]     BYTE      *pbData,
  [in, out] DWORD     *pdwDataLen
);

Параметры

[in] hKey

Дескриптор ключа для экспорта.

[in] hExpKey

Дескриптор криптографического ключа целевого пользователя. Данные ключа в экспортируемом blOB-объекте ключа шифруются с помощью этого ключа. Это гарантирует, что только конечный пользователь сможет использовать ключевой BLOB-объект. HExpKey и hKey должны поступать из одного поставщика служб конфигурации.

Чаще всего это открытый ключ обмена ключами целевого пользователя. Однако некоторые протоколы в некоторых CSP требуют, чтобы для этой цели использовался ключ сеанса, принадлежащий конечному пользователю.

Если тип ключа BLOB, заданный параметром dwBlobType , — PUBLICKEYBLOB, этот параметр не используется и должен иметь нулевое значение.

Если тип ключа BLOB, заданный параметром dwBlobType , — PRIVATEKEYBLOB, обычно это дескриптор сеансового ключа, который должен использоваться для шифрования ключа BLOB. Некоторые поставщики служб конфигурации допускают нулевое значение этого параметра. В этом случае приложение должно зашифровать большой двоичный объект закрытого ключа вручную, чтобы защитить его.

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

Примечание Некоторые поставщики служб конфигурации могут изменять этот параметр в результате операции. Приложения, которые впоследствии используют этот ключ для других целей, должны вызывать функцию CryptDuplicateKey для создания дескриптора дубликата ключа. Когда приложение завершит использование дескриптора, отпустите его, вызвав функцию CryptDeographyKey .
 

[in] dwBlobType

Указывает тип ключа BLOB для экспорта в pbData. Это должна быть одна из следующих констант, как описано в разделе Хранилище криптографических ключей и Exchange.

Значение Значение
OPAQUEKEYBLOB
Используется для хранения ключей сеанса в Schannel CSP или в любом другом формате, зависят от поставщика. OPAQUEKEYBLOB не являются передаваемыми и должны использоваться в CSP, создавшей большой двоичный объект.
PRIVATEKEYBLOB
Используется для передачи пар открытого и закрытого ключей.
PUBLICKEYBLOB
Используется для передачи открытых ключей.
SIMPLEBLOB
Используется для передачи ключей сеанса.
PLAINTEXTKEYBLOB
ОБЪЕКТ PLAINTEXTKEYBLOB, используемый для экспорта любого ключа, поддерживаемого используемым поставщиком служб конфигурации.
SYMMETRICWRAPKEYBLOB
Используется для экспорта и импорта симметричного ключа , заключенного в другой симметричный ключ. Фактический ключ в оболочке имеет формат, указанный в стандарте RFC 3217 IETF.

[in] dwFlags

Задает дополнительные параметры для функции. Этот параметр может быть равен нулю или сочетанию одного или нескольких из следующих значений.

Значение Значение
CRYPT_BLOB_VER3
0x00000080
Этот флаг заставляет эту функцию экспортировать версию 3 типа BLOB.
CRYPT_DESTROYKEY
0x00000004
Этот флаг уничтожает исходный ключ в OPAQUEKEYBLOB. Этот флаг доступен только в Schannel CSP.
CRYPT_OAEP
0x00000040
Этот флаг приводит к созданию форматирования PKCS #1 версии 2 с шифрованием и расшифровкой RSA при экспорте SIMPLEBLOB.
CRYPT_SSL2_FALLBACK
0x00000002
Первые восемь байтов заполнения блока шифрования RSA должны иметь значение 0x03, а не случайные данные. Это предотвращает откаты версий и рассматривается в спецификации SSL3. Этот флаг доступен только для Schannel CSP.
CRYPT_Y_ONLY
0x00000001
Этот флаг не используется.

[out] pbData

Указатель на буфер, который получает ключевые данные БОЛЬШОГО ДВОИЧНОГО ОБЪЕКТА . Формат этого большого двоичного объекта зависит от типа большого двоичного объекта, запрошенного в параметре dwBlobType . Формат для PRIVATEKEYBLOB, PUBLICKEYBLOB и SIMPLEBLOB см. в разделе Базовые BLOB-объекты ключа поставщика.

Если этот параметр имеет значение NULL, требуемый размер буфера помещается в значение, на которое указывает параметр pdwDataLen . Дополнительные сведения см. в разделе Извлечение данных неизвестной длины.

[in, out] pdwDataLen

Указатель на значение DWORD , которое в записи содержит размер буфера в байтах, на который указывает параметр pbData . При возврате функции это значение содержит количество байтов, хранящихся в буфере.

Примечание При обработке данных, возвращаемых в буфере, приложения должны использовать фактический размер возвращаемых данных. Фактический размер может быть немного меньше размера буфера, указанного на входных данных. На входных данных размеры буфера обычно указываются достаточно большими, чтобы обеспечить максимально возможное хранение выходных данных в буфере. В выходных данных переменная, на которую указывает этот параметр, обновляется с учетом фактического размера данных, скопированных в буфер.
 
Чтобы получить требуемый размер буфера pbData , передайте значение NULL для pbData. Требуемый размер буфера будет помещен в значение, на которое указывает этот параметр.

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

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

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

Коды ошибок, предваряемые "NTE", создаются конкретным поставщиком служб конфигурации. В следующей таблице показаны некоторые возможные коды ошибок.

Код возврата Описание
ERROR_INVALID_HANDLE
Один из параметров указывает недопустимый дескриптор.
ERROR_INVALID_PARAMETER
Один из параметров содержит недопустимое значение. Чаще всего это недопустимый указатель.
ERROR_MORE_DATA
Если буфер, заданный параметром pbData , недостаточно велик для хранения возвращаемых данных, функция задает код ERROR_MORE_DATA и сохраняет требуемый размер буфера в байтах в переменной, на которую указывает pdwDataLen.
NTE_BAD_DATA
Либо алгоритм, который работает с открытым ключом для экспорта, не поддерживается этим поставщиком служб конфигурации, либо предпринята попытка экспортировать сеансовый ключ, зашифрованный с помощью другого открытого ключа.
NTE_BAD_FLAGS
Параметр dwFlags не равен нулю.
NTE_BAD_KEY
Один или оба ключа, указанные hKey и hExpKey , недопустимы.
NTE_BAD_KEY_STATE
У вас нет разрешения на экспорт ключа. То есть при создании ключа hKey флаг CRYPT_EXPORTABLE не был указан.
NTE_BAD_PUBLIC_KEY
Тип ключа BLOB , заданный dwBlobType , — PUBLICKEYBLOB, но hExpKey не содержит дескриптор открытого ключа.
NTE_BAD_TYPE
Параметр dwBlobType указывает неизвестный тип BLOB.
NTE_BAD_UID
Не удается найти контекст CSP, указанный при создании ключа hKey .
NTE_NO_KEY
Ключ сеанса экспортируется, а параметр hExpKey не указывает открытый ключ.

Комментарии

Для любых перестановок клавиш DES, использующих ОБЪЕКТ PLAINTEXTKEYBLOB, можно экспортировать только полный размер ключа, включая бит четности. Поддерживаются следующие размеры ключей.

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

Примеры

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

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

BOOL GetExportedKey(
    HCRYPTKEY hKey, 
    DWORD dwBlobType,
    LPBYTE *ppbKeyBlob, 
    LPDWORD pdwBlobLen)
{
    DWORD dwBlobLength;
    *ppbKeyBlob = NULL;
    *pdwBlobLen = 0;

    // Export the public key. Here the public key is exported to a 
    // PUBLICKEYBLOB. This BLOB can be written to a file and
    // sent to another user.

    if(CryptExportKey(   
        hKey,    
        NULL,    
        dwBlobType,
        0,    
        NULL, 
        &dwBlobLength)) 
    {
        printf("Size of the BLOB for the public key determined. \n");
    }
    else
    {
        printf("Error computing BLOB length.\n");
        return FALSE;
    }

    // Allocate memory for the pbKeyBlob.
    if(*ppbKeyBlob = (LPBYTE)malloc(dwBlobLength)) 
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        printf("Out of memory. \n");
        return FALSE;
    }

    // Do the actual exporting into the key BLOB.
    if(CryptExportKey(   
        hKey, 
        NULL,    
        dwBlobType,    
        0,    
        *ppbKeyBlob,    
        &dwBlobLength))
    {
        printf("Contents have been written to the BLOB. \n");
        *pdwBlobLen = dwBlobLength;
    }
    else
    {
        printf("Error exporting key.\n");
        free(*ppbKeyBlob);
        *ppbKeyBlob = NULL;

        return FALSE;
    }

    return TRUE;
}

Требования

Требование Значение
Минимальная версия клиента Windows XP [только классические приложения]
Минимальная версия сервера Windows Server 2003 [только классические приложения]
Целевая платформа Windows
Header wincrypt.h
Библиотека Advapi32.lib
DLL Advapi32.dll

См. также раздел

CryptImportKey

Функции создания ключей и обмена