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

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

В CryptoAPI были внесены важные изменения для поддержки взаимодействия с электронной почтой S /MIME, влияющие на обработку сообщений в конвертах. Дополнительные сведения см. в разделе Примечания статьи 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

Логическое значение, указывающее, является ли этот раздел последним в ряде, который шифруется. Параметр 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.

Если pbData имеет значение NULL, ошибка не возвращается, а функция сохраняет размер зашифрованных данных в байтах в значении 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
Данные, которые необходимо зашифровать, являются недопустимыми. Например, если используется блочный шифр и флаг Final имеет значение 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, чтобы модуль шифрования смог правильно завершить процесс шифрования. Если значение Final имеет значение 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)
}

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

Примеры

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

Требования

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

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

CryptCreateHash

CryptDecrypt

CryptGenKey

CryptGetHashParam

CryptGetKeyParam

CryptImportKey

CryptMsgOpenToEncode

CryptSignHash

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