CryptDecrypt 函数 (wincrypt.h)
为支持 安全/多用途 Internet 邮件扩展 (S/MIME) 电子邮件互操作性,已对影响信封邮件处理的 CryptoAPI 进行了重要更改。 有关详细信息,请参阅 CryptMsgOpenToEncode 的“备注”部分。
语法
BOOL CryptDecrypt(
[in] HCRYPTKEY hKey,
[in] HCRYPTHASH hHash,
[in] BOOL Final,
[in] DWORD dwFlags,
[in, out] BYTE *pbData,
[in, out] DWORD *pdwDataLen
);
参数
[in] hKey
用于解密的密钥的句柄。 应用程序使用 CryptGenKey 或 CryptImportKey 函数获取此句 柄 。
此密钥指定要使用的解密算法。
[in] hHash
哈希对象的句柄。 如果要同时解密和哈希数据,则会在此参数中传递哈希对象的句柄。 哈希值使用解密的 纯文本进行更新。 此选项在同时解密和验证签名时很有用。
在调用 CryptDecrypt 之前,应用程序必须通过调用 CryptCreateHash 函数来获取哈希对象的句柄。 解密完成后,可以使用 CryptGetHashParam 函数获取哈希值,也可以使用 CryptSignHash 函数对其进行签名,也可以使用 CryptVerifySignature 函数来验证数字签名。
如果不执行任何哈希,则此参数必须为零。
[in] Final
一个布尔值,指定此是否是正在解密的序列中的最后一个部分。 如果这是最后一个或唯一的块,则此值为 TRUE 。 如果这不是最后一个块,则此值为 FALSE。 有关详细信息,请参阅“备注”。
[in] dwFlags
定义了以下标志值。
值 | 含义 |
---|---|
|
使用最佳非对称加密填充 (OAEP) (PKCS #1 版本 2) 。 只有具有 RSA 加密/解密功能的 Microsoft 增强型加密提供程序 才支持此标志。 此标志不能与 CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 标志组合使用。 |
|
在不检查填充的情况下对 BLOB 执行解密。 只有具有 RSA 加密/解密功能的 Microsoft 增强型加密提供程序 才支持此标志。 此标志不能与 CRYPT_OAEP 标志组合使用。 |
[in, out] pbData
指向包含要解密的数据的缓冲区的指针。 执行解密后,将纯文本放回同一缓冲区。
此缓冲区中的加密字节数由 pdwDataLen 指定。
[in, out] pdwDataLen
指向指示 pbData 缓冲区长度的 DWORD 值的指针。 调用此函数之前,调用应用程序将 DWORD 值设置为要解密的字节数。 返回后, DWORD 值包含解密的明文的字节数。
使用 块密码 时,此数据长度必须是块大小的倍数,除非这是要解密的数据的最后一部分, 并且 Final 参数为 TRUE。
返回值
如果函数成功,则函数) 返回非零 (TRUE 。
如果函数失败,则返回零 (FALSE) 。 有关扩展的错误信息,请调用 GetLastError。
NTE 开头的错误代码由使用的特定 CSP 生成。 一些可能的错误代码随之而来。
值 | 说明 |
---|---|
|
其中一个参数指定无效的句柄。 |
|
其中一个参数包含无效的值。 这通常是无效的指针。 |
|
hKey会话密钥指定此 CSP 不支持的算法。 |
|
要解密的数据无效。 例如,如果使用块密码并且 Final 标志为 FALSE, 则 pdwDataLen 指定的值必须是块大小的倍数。 如果发现 填充 无效,也可能返回此错误。 |
|
dwFlags 参数为非零。 |
|
hHash 参数包含无效的句柄。 |
|
hKey 参数不包含密钥的有效句柄。 |
|
输出缓冲区的大小太小,无法保存生成的纯文本。 |
|
找不到在创建密钥时指定的 CSP 上下文。 |
|
应用程序尝试解密相同数据两次。 |
|
函数以某种意外方式失败。 |
注解
如果要解密大量数据,可以通过重复调用 CryptDecrypt 在分区中完成解密。 只有在最后一次调用 CryptDecrypt 时,Final 参数才能设置为 TRUE,以便解密引擎可以正确完成解密过程。 当 Final 为 TRUE 时,将执行以下额外操作:
- 如果密钥是块密码键,则数据将填充到该密码块大小的倍数。 若要查找密码的块大小,请使用 CryptGetKeyParam 获取密钥的KP_BLOCKLEN值。
- 如果密码在 链接模式下运行,则下一个 CryptDecrypt 操作会将密码的反馈寄存器重置为密钥的KP_IV值。
- 如果密码是 流密码,则下一个 CryptDecrypt 调用会将密码重置为其初始 状态。
如果不将 Final 参数设置为 TRUE,则无法将密码的反馈寄存器设置为密钥的KP_IV值。 如果需要,例如不想添加其他填充块或更改每个块的大小,可以通过使用 CryptDuplicateKey 函数创建原始密钥的副本并将重复键传递给 CryptDecrypt 函数来模拟此操作。 这会导致原始密钥的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)
// Decrypt the block with the duplicate key.
CryptDecrypt(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 密钥的模数长度相同。 如果密码文本在最重要的字节中具有零,则必须将这些字节包含在输入数据缓冲区和输入缓冲区长度中。 密码文本必须采用 little endian 格式。
示例
有关使用此函数的示例,请参阅 示例 C 程序:解密文件。
要求
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | wincrypt.h |
Library | Advapi32.lib |
DLL | Advapi32.dll |
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈