cryptExportKey 函数 (wincrypt.h)
要导出的密钥的句柄传递给函数,函数返回 密钥 BLOB。 此密钥 BLOB 可以通过不安全的传输发送,也可以存储在不安全的存储位置。 此函数可以导出 Schannel 会话密钥、常规 会话密钥、 公钥或 公钥/私钥对。 要导出的密钥 BLOB 在目标接收方使用其上的 CryptImportKey 函数将密钥或密钥对导入收件人的 CSP 之前是无用的。
BOOL CryptExportKey(
[in] HCRYPTKEY hKey,
[in] HCRYPTKEY hExpKey,
[in] DWORD dwBlobType,
[in] DWORD dwFlags,
[out] BYTE *pbData,
[in, out] DWORD *pdwDataLen
);
[in] hKey
要导出的密钥的句柄。
[in] hExpKey
目标用户的加密密钥的句柄。 导出的 密钥 BLOB 中的密钥 数据使用此密钥进行加密。 这可确保只有目标用户才能使用密钥 BLOB。 hExpKey 和 hKey 必须来自同一 CSP。
大多数情况下,这是目标用户的 密钥交换公钥 。 但是,某些 CSP 中的某些协议要求将属于目标用户的会话密钥用于此目的。
如果 dwBlobType 指定的密钥 BLOB 类型为 PUBLICKEYBLOB,则此参数未使用,必须设置为零。
如果 dwBlobType 指定的密钥 BLOB 类型为 PRIVATEKEYBLOB,则这通常是用于加密密钥 BLOB 的会话密钥的句柄。 某些 CSP 允许此参数为零,在这种情况下,应用程序必须手动加密 私钥 BLOB 才能保护它。
若要确定 Microsoft 加密服务提供程序如何响应此参数,请参阅 Microsoft 加密服务提供程序的私钥 BLOB 部分。
[in] dwBlobType
指定要在 pbData 中导出的密钥 BLOB 的类型。 这必须是加密密钥 存储和 Exchange 中所述的下列常量之一。
值 | 含义 |
---|---|
|
用于以 Schannel CSP 或任何其他特定于供应商的格式存储会话密钥。 OPAQUEKEYBLOB 不可转让,必须在生成 BLOB 的 CSP 中使用。 |
|
用于传输 公钥/私钥对。 |
|
用于传输公钥。 |
|
用于传输会话密钥。 |
|
用于导出正在使用的 CSP 支持的任何密钥的 PLAINTEXTKEYBLOB 。 |
|
用于导出和导入用另一个 对称密钥 包装的对称密钥。 实际的包装密钥采用 IETF RFC 3217 标准中指定的格式。 |
[in] dwFlags
指定函数的其他选项。 此参数可以是零,也可以是以下一个或多个值的组合。
值 | 含义 |
---|---|
|
此标志使此函数导出 BLOB 类型的版本 3。 |
|
此标志销毁 OPAQUEKEYBLOB 中的原始密钥。 此标志仅在 Schannel CSP 中可用。 |
|
此标志会导致在导出 SIMPLEB BLOB 时使用 RSA 加密和解密创建 PKCS #1 版本 2 格式设置。 |
|
RSA 加密块 填充 的前八个字节必须设置为0x03而不是随机数据。 这可以防止版本回滚攻击,SSL3 规范中对此进行了讨论。 此标志仅适用于 Schannel CSP。 |
|
未使用此标志。 |
[out] pbData
指向接收 密钥 BLOB 数据的缓冲区的指针。 此 BLOB 的格式因 dwBlobType 参数中请求的 BLOB 类型而异。 有关 PRIVATEKEYBLOBs、PUBLICKEYBLOBs 和 SIMPLEBLOB 的格式,请参阅 基提供程序密钥 BLOB。
如果此参数为 NULL,则将所需的缓冲区大小放置在 pdwDataLen 参数指向的值中。 有关详细信息,请参阅 检索未知长度的数据。
[in, out] pdwDataLen
指向 DWORD 值的指针,该值在输入时包含 pbData 参数指向的缓冲区的大小(以字节为单位)。 当函数返回时,此值包含缓冲区中存储的字节数。
如果函数成功,则函数) 返回非零 (TRUE 。
如果函数失败,它将返回零 (FALSE) 。 有关扩展的错误信息,请调用 GetLastError。
以“NTE”开头的错误代码由使用的特定 CSP 生成。 下表显示了一些可能的错误代码。
返回代码 | 说明 |
---|---|
|
其中一个参数指定无效的句柄。 |
|
其中一个参数包含无效的值。 这通常是无效的指针。 |
|
如果 pbData 参数指定的缓冲区不够大,无法容纳返回的数据,该函数将设置ERROR_MORE_DATA代码,并将所需的缓冲区大小(以字节为单位)存储在 pdwDataLen 指向的变量中。 |
|
此 CSP 不支持与要导出的公钥一起使用的算法,或者尝试导出使用公钥以外的其他内容加密的会话密钥。 |
|
dwFlags 参数为非零值。 |
|
hKey 和 hExpKey 指定的一个或两个密钥无效。 |
|
您没有导出密钥的权限。 也就是说,创建 hKey 键时,未指定CRYPT_EXPORTABLE标志。 |
|
dwBlobType 指定的密钥 BLOB 类型为 PUBLICKEYBLOB,但 hExpKey 不包含公钥句柄。 |
|
dwBlobType 参数指定未知的 BLOB 类型。 |
|
找不到创建 hKey 密钥时指定的 CSP 上下文。 |
|
正在导出会话密钥, hExpKey 参数未指定公钥。 |
对于使用 PLAINTEXTKEYBLOB 的任何 DES 密钥排列,只能导出完整的密钥大小,包括奇偶校验位。 支持以下密钥大小。
算法 | 支持的密钥大小 |
---|---|
CALG_DES | 64 位 |
CALG_3DES_112 | 128 位 |
CALG_3DES | 192 位 |
以下示例演示如何以更安全的方式导出加密密钥或密钥对。 此示例假定已获取加密上下文,并且公钥可用于导出。 有关包含使用此函数的完整上下文的示例,请参阅 示例 C 程序:对哈希进行签名和验证哈希签名。 有关使用此函数的另一个示例,请参阅 示例 C 程序:导出会话密钥。
#include <windows.h>
#include <stdio.h>
#include <Wincrypt.h>
BOOL GetExportedKey(
HCRYPTKEY hKey,
DWORD dwBlobType,
LPBYTE *ppbKeyBlob,
LPDWORD pdwBlobLen)
{
DWORD dwBlobLength;
*ppbKeyBlob = NULL;
*pdwBlobLen = 0;
// Export the public key. Here the public key is exported to a
// PUBLICKEYBLOB. This BLOB can be written to a file and
// sent to another user.
if(CryptExportKey(
hKey,
NULL,
dwBlobType,
0,
NULL,
&dwBlobLength))
{
printf("Size of the BLOB for the public key determined. \n");
}
else
{
printf("Error computing BLOB length.\n");
return FALSE;
}
// Allocate memory for the pbKeyBlob.
if(*ppbKeyBlob = (LPBYTE)malloc(dwBlobLength))
{
printf("Memory has been allocated for the BLOB. \n");
}
else
{
printf("Out of memory. \n");
return FALSE;
}
// Do the actual exporting into the key BLOB.
if(CryptExportKey(
hKey,
NULL,
dwBlobType,
0,
*ppbKeyBlob,
&dwBlobLength))
{
printf("Contents have been written to the BLOB. \n");
*pdwBlobLen = dwBlobLength;
}
else
{
printf("Error exporting key.\n");
free(*ppbKeyBlob);
*ppbKeyBlob = NULL;
return FALSE;
}
return TRUE;
}
要求 | 值 |
---|---|
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | wincrypt.h |
Library | Advapi32.lib |
DLL | Advapi32.dll |