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


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

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

Важные изменения в поддержке Secure/Multipurpose Internet Mail Extensions (S/MIME) для взаимодействия с электронной почтой были сделаны в CryptoAPI, которые влияют на обработку конвертированных сообщений. Дополнительные сведения см. в разделе "Примечания" CryptMsgOpenToEncode.

Важное Функция CryptEncrypt не гарантируется безопасной для потока и может возвращать неверные результаты при одновременном вызове несколькими вызывающими абонентами.
 

Синтаксис

BOOL CryptEncrypt(
  [in]      HCRYPTKEY  hKey,
  [in]      HCRYPTHASH hHash,
  [in]      BOOL       Final,
  [in]      DWORD      dwFlags,
  [in, out] BYTE       *pbData,
  [in, out] DWORD      *pdwDataLen,
  [in]      DWORD      dwBufLen
);

Параметры

[in] hKey

Дескриптор ключа шифрования. Приложение получает этот дескриптор с помощью функции CryptGenKey или функции CryptImportKey.

Ключ задает используемый алгоритм шифрования.

[in] hHash

Дескриптор хэш-объекта . Если данные должны быть хэшированы и зашифрованы одновременно, дескриптор в хэш-объект можно передать в параметре hHash. Хэш-значение обновляется с помощью открытого текста. Этот параметр полезен при создании подписанного и зашифрованного текста.

Перед вызовом CryptEncryptприложение должно получить дескриптор хэш-объекта, вызвав функцию CryptCreateHash. После завершения шифрования хэш-значение можно получить с помощью функции CryptGetHashParam или хэша можно подписать с помощью функции CryptSignHash.

Если хэш не выполняется, этот параметр должен быть null.

[in] Final

Логическое значение, указывающее, является ли это последним разделом в зашифрованном ряде. Окончательный имеет значение TRUE для последнего или только блока и false, если требуется зашифровать больше блоков. Дополнительные сведения см. в разделе "Примечания".

[in] dwFlags

Следующее dwFlags значение определяется, но зарезервировано для дальнейшего использования.

Ценность Значение
CRYPT_OAEP
Используйте оптимальную асимметричную заполнения шифрования (OAEP) (PKCS #1 версии 2). Этот флаг поддерживается только расширенным поставщиком шифрования Майкрософт с шифрованием ИЛИ расшифровкой RSA.

[in, out] pbData

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

Параметр pdwDataLen указывает на переменную, содержащую длину в байтах открытого текста. Параметр dwBufLen содержит общий размер этого буфера в байтах.

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

[in, out] pdwDataLen

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

Если буфер, выделенный для pbData, недостаточно велик для хранения зашифрованных данных, GetLastError возвращает ERROR_MORE_DATA и сохраняет требуемый размер буфера в байтах в значение DWORD, указываемое на pdwDataLen.

Если pbDataNULL, ошибка не возвращается, а функция сохраняет размер зашифрованных данных в байтах в значении DWORD, на которое указывает pdwDataLen. Это позволяет приложению определить правильный размер буфера.

При использовании блочного шифра эта длина данных должна быть кратной, если только это не последний раздел данных, который необходимо зашифровать, и параметр Final имеет значение TRUE.

[in] dwBufLen

Указывает общий размер в байтах входного буфера pbData.

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

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

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

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

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

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

Ценность Описание
ERROR_INVALID_HANDLE
Один из параметров задает недопустимый дескриптор.
ERROR_INVALID_PARAMETER
Один из параметров содержит недопустимое значение. Чаще всего это недопустимый указатель.
NTE_BAD_ALGID
Ключ сеанса hKey задает алгоритм, который не поддерживается этим поставщиком служб CSP.
NTE_BAD_DATA
Зашифрованные данные недопустимы. Например, если используется шифр блока и флаг окончательного имеет значение false FALSE, то значение, указанное в pdwDataLen, должно иметь несколько размеров блока.
NTE_BAD_FLAGS
Параметр dwFlags ненулево.
NTE_BAD_HASH
Параметр hHash содержит недопустимый дескриптор.
NTE_BAD_HASH_STATE
Предпринята попытка добавить данные в хэш-объект, который уже помечен как "завершен".
NTE_BAD_KEY
Параметр hKey не содержит допустимый дескриптор ключа.
NTE_BAD_LEN
Размер выходного буфера слишком мал, чтобы сохранить созданный зашифрованный текст.
NTE_BAD_UID
Контекст CSP, указанный при создании ключа, не найден.
NTE_DOUBLE_ENCRYPT
Приложение попыталось зашифровать одни и те же данные дважды.
NTE_FAIL
Функция завершилась сбоем каким-то неожиданным образом.
NTE_NO_MEMORY
CSP не хватает памяти во время операции.

Замечания

Если требуется зашифровать большое количество данных, его можно сделать в разделах, вызвав CryptEncrypt многократно. Параметр Final должен иметь значение TRUE при последнем вызове CryptEncrypt, чтобы модуль шифрования смог правильно завершить процесс шифрования. Следующие дополнительные действия выполняются при окончательныхTRUE:

  • Если ключ является ключом блочного шифра, данные заполняются на несколько размеров блока шифра. Если длина данных равна размеру блока шифра, к данным добавляется один дополнительный блок заполнения. Чтобы найти размер блока шифра, используйте CryptGetKeyParam, чтобы получить значение KP_BLOCKLEN ключа.
  • Если шифр работает в режиме цепочки , следующая операция CryptEncrypt сбрасывает регистр обратной связи шифра в значение KP_IV ключа.
  • Если шифр являетсяшифром потока , следующий CryptEncrypt сбрасывает шифр в исходное состояние .

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

// Set the IV for the original key. Do not use the original key for 
// encryption or decryption after doing this because the key's 
// feedback register will get modified and you cannot change it.
CryptSetKeyParam(hOriginalKey, KP_IV, newIV)

while(block = NextBlock())
{
    // Create a duplicate of the original key. This causes the 
    // original key's IV to be copied into the duplicate key's 
    // feedback register.
    hDuplicateKey = CryptDuplicateKey(hOriginalKey)

    // Encrypt the block with the duplicate key.
    CryptEncrypt(hDuplicateKey, block)

    // Destroy the duplicate key. Its feedback register has been 
    // modified by the CryptEncrypt function, so it cannot be used
    // again. It will be re-duplicated in the next iteration of the 
    // loop.
    CryptDestroyKey(hDuplicateKey)
}

расширенного поставщика шифрования Майкрософт поддерживает прямое шифрование с помощью RSAоткрытых ключей и расшифровки с помощью закрытых ключей RSA . Шифрование использует PKCS #1 заполнение. При расшифровке этот заполнение проверяется. Длина данных с открытым текстом, которые можно зашифровать с помощью вызова CryptEncrypt с ключом RSA, — это длина модуля ключа минус одиннадцать байтов. Одиннадцать байтов является выбранным минимумом для заполнения PKCS #1. Шифр возвращается в формате маленький.

Примеры

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

Требования

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

См. также

CryptCreateHash

CryptDecrypt

CryptGenKey

CryptGetHashParam

CryptGetKeyParam

CryptImportKey

CryptMsgOpenToEncode

CryptSignHash

функции шифрования и расшифровки данных