CryptEncrypt 函数 (wincrypt.h)

重要 此 API 已弃用。 新的和现有的软件应开始使用 加密下一代 API。 Microsoft 可能会在将来的版本中删除此 API。
 
CryptEncrypt 函数加密数据。 用于加密数据的算法由 CSP 模块持有的密钥指定,并由 hKey 参数引用。

为支持 安全/多用途 Internet 邮件扩展 (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

一个布尔值,指定此是否是正在加密的序列中的最后一节。 对于 最后一个或唯一的块,Final 设置为 TRUE ;如果要加密更多块,则设置为 FALSE 。 有关详细信息,请参阅“备注”。

[in] dwFlags

以下 dwFlags 值已定义,但保留以供将来使用。

含义
CRYPT_OAEP
使用最佳非对称加密填充 (OAEP) (PKCS #1 版本 2) 。 只有具有 RSA 加密/解密功能的 Microsoft 增强型加密提供程序 才支持此标志。

[in, out] pbData

指向包含要加密的纯文本的缓冲区的指针。 此缓冲区中的纯文本将被此函数创建的 密文 覆盖。

pdwDataLen 参数指向包含纯文本长度(以字节为单位)的变量。 dwBufLen 参数包含此缓冲区的总大小(以字节为单位)。

如果此参数包含 NULL,则此函数将计算密码文本所需的大小,并将其放在 pdwDataLen 参数指向的值中。

[in, out] pdwDataLen

指向 DWORD 值的指针,该值在输入时包含 pbData 缓冲区中纯文本的长度(以字节为单位)。 退出时,此 DWORD 包含写入 pbData 缓冲区的密码文本的长度(以字节为单位)。

如果为 pbData 分配的缓冲区不够大,无法保存加密数据,GetLastError 将返回ERROR_MORE_DATA并将所需的缓冲区大小(以字节为单位)存储在 pdwDataLen 指向的 DWORD 值中。

如果 pbDataNULL,则不返回错误,并且该函数将加密数据的大小(以字节为单位)存储在 pdwDataLen 指向的 DWORD 值中。 这样,应用程序就可以确定正确的缓冲区大小。

使用 块密码 时,此数据长度必须是块大小的倍数,除非这是要加密的数据的最后一部分, 并且 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 在部分完成此操作。 最后一次调用 CryptEncrypt 时,必须将 Final 参数设置为 TRUE,以便加密引擎可以正确完成加密过程。 当 FinalTRUE 时,将执行以下额外操作:

  • 如果密钥是块密码键,则数据将填充到该密码块大小的倍数。 如果数据长度等于密码的块大小,则会向数据追加一个额外的填充块。 若要查找密码的块大小,请使用 CryptGetKeyParam 获取密钥的KP_BLOCKLEN值。
  • 如果密码在 链接模式下运行,则下一个 CryptEncrypt 操作会将密码的反馈寄存器重置为密钥的KP_IV值。
  • 如果密码是 流密码,则下一个 CryptEncrypt 会将该密码重置为其初始 状态

如果不将 Final 参数设置为 TRUE,则无法将密码的反馈寄存器设置为密钥的KP_IV值。 如果需要,例如,在不想添加其他填充块或更改每个块的大小的情况下,可以通过使用 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 增强型加密提供程序支持使用 RSA公钥进行直接加密,支持使用 RSA 私钥进行解密。 加密使用 PKCS #1 填充。 解密时,验证此填充。 使用 RSA 密钥调用 CryptEncrypt 可以加密的纯文本数据的长度是密钥模数减去 11 个字节的长度。 11 个字节是 PKCS #1 填充选择的最小值。 密码文本以 little endian 格式返回。

示例

有关使用此函数的示例,请参阅示例 C 程序:加密文件和示例 C 程序:解密文件

要求

要求
最低受支持的客户端 Windows XP [仅限桌面应用]
最低受支持的服务器 Windows Server 2003 [仅限桌面应用]
目标平台 Windows
标头 wincrypt.h
Library Advapi32.lib
DLL Advapi32.dll

另请参阅

CryptCreateHash

CryptDecrypt

CryptGenKey

CryptGetHashParam

CryptGetKeyParam

CryptImportKey

CryptMsgOpenToEncode

CryptSignHash

数据加密和解密函数