CryptEncrypt 函数 (wincrypt.h)
对支持 安全/多用途 Internet 邮件扩展(S/MIME)电子邮件互操作性的重要更改已经对影响信封邮件处理的 CryptoAPI 进行了。 有关详细信息,请参阅 CryptMsgOpenToEncode的“备注”部分。
语法
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 值,但保留以供将来使用。
价值 | 意义 |
---|---|
|
使用最佳非对称加密填充 (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 生成。 下面是一些可能的错误代码。
价值 | 描述 |
---|---|
|
其中一个参数指定无效的句柄。 |
|
其中一个参数包含无效的值。 这通常是无效的指针。 |
|
hKey会话密钥 指定此 CSP 不支持的算法。 |
|
要加密的数据无效。 例如,使用块密码并且 最终 标志 FALSE时,由 pdwDataLen 指定的值必须是块大小的倍数。 |
|
dwFlags 参数为非零。 |
|
hHash 参数包含无效的句柄。 |
|
尝试将数据添加到已标记为“已完成”的哈希对象。 |
|
hKey 参数不包含密钥的有效句柄。 |
|
输出缓冲区的大小太小,无法保存生成的密码文本。 |
|
找不到创建密钥时指定的 CSP 上下文。 |
|
应用程序尝试加密同一数据两次。 |
|
函数以某种意外的方式失败。 |
|
在操作期间,CSP 内存不足。 |
言论
如果要加密大量数据,可以通过重复调用 CryptEncrypt,在节中执行此操作。 Final 参数必须在上次调用 CryptEncrypt时设置为 TRUE,以便加密引擎能够正确完成加密过程。 当 最终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 增强型加密提供程序 支持使用 RSA 公钥进行直接加密,并使用 RSA 私钥进行解密。 加密使用 PKCS #1 填充。 在解密时,会验证此填充。 可以通过调用 CryptEncrypt 和 RSA 密钥进行加密的纯文本数据的长度是密钥模量减去 11 个字节的长度。 11 个字节是 PKCS #1 填充选择的最小值。 密码文本以 小端 格式返回。
例子
有关使用此函数的示例,请参阅 示例 C 程序:加密文件 和 示例 C 程序:解密文件。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows XP [仅限桌面应用] |
支持的最低服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | 窗户 |
标头 | wincrypt.h |
库 | Advapi32.lib |
DLL | Advapi32.dll |