cryptImportKey 函数 (wincrypt.h)

重要 此 API 已弃用。 新的和现有的软件应开始使用 加密下一代 API。 Microsoft 可能会在将来的版本中删除此 API。
 
CryptImportKey 函数将加密密钥密钥 BLOB 传输到加密服务提供程序 (CSP) 。 此函数可用于导入 Schannel会话密钥、常规会话密钥、 公钥公钥/私钥对。 对于除公钥之外的所有密钥,密钥或密钥对都是加密的。

语法

BOOL CryptImportKey(
  [in]  HCRYPTPROV hProv,
  [in]  const BYTE *pbData,
  [in]  DWORD      dwDataLen,
  [in]  HCRYPTKEY  hPubKey,
  [in]  DWORD      dwFlags,
  [out] HCRYPTKEY  *phKey
);

参数

[in] hProv

使用 CryptAcquireContext 函数获取的 CSP 的句柄。

[in] pbData

一个 BYTE 数组,其中包含一个 PUBLICKEYSTRUC BLOB 标头,后跟加密密钥。 此密钥 BLOB 由 CryptExportKey 函数创建,此应用程序或可能在另一台计算机上运行的其他应用程序创建。

[in] dwDataLen

包含密钥 BLOB 的长度(以字节为单位)。

[in] hPubKey

解密 pbData 中存储的密钥的加密密钥的句柄。 此密钥必须来自 hProv 引用的同一 CSP。 此参数的含义因 CSP 类型和要导入的密钥 BLOB 的类型而异:

  • 如果使用密钥 交换密钥对(例如 SIMPLEBLOB)加密密钥 BLOB,则此参数可以是密钥交换密钥的句柄。
  • 如果使用会话密钥(例如加密的 PRIVATEKEYBLOB)对密钥 BLOB 进行加密,则此参数包含此会话密钥的句柄。
  • 如果密钥 BLOB 未加密(例如 PUBLICKEYBLOB),则不会使用此参数,并且必须为零。
  • 如果使用 Schannel CSP 中的会话密钥对密钥 BLOB 进行加密,例如,加密的 OPAQUEKEYBLOB 或任何其他特定于供应商的 OPAQUEKEYBLOB,则不会使用此参数,并且必须设置为零。
注意 某些 CSP 可能会因操作而修改此参数。 随后将此密钥用于其他目的的应用程序应调用 CryptDuplicateKey 函数来创建重复的密钥句柄。 当应用程序使用完句柄后,通过调用 CryptDestroyKey 函数释放它。
 

[in] dwFlags

当前仅在将 PRIVATEKEYBLOB 形式的公钥/私钥对导入 CSP 时使用。

此参数的取值可为下列值之一:

含义
CRYPT_EXPORTABLE
要导入的密钥最终将重新导出。 如果未使用此标志,则调用具有密钥句柄的 CryptExportKey 会失败。
CRYPT_OAEP
此标志会导致在导入 SIMPLEBLOB时使用 RSA 加密和解密检查 PKCS #1 版本 2 格式设置。
CRYPT_NO_SALT
为 40 位对称密钥分配无盐值。 有关详细信息,请参阅 Salt 值功能
CRYPT_USER_PROTECTED
如果设置了此标志,则当尝试使用此密钥执行某些操作时,CSP 将通过对话框或其他方法通知用户。 精确行为由使用的 CSP 或 CSP 类型指定。 如果获取提供程序上下文时设置了CRYPT_SILENT,则使用此标志会导致失败,并且最后一个错误设置为NTE_SILENT_CONTEXT。
CRYPT_IPSEC_HMAC_KEY
允许导入大于 16 个字节的 RC2 密钥。 如果未设置此标志,则调用具有大于 16 字节的 RC2 键的 CryptImportKey 函数将失败,对 GetLastError 的调用将返回 NTE_BAD_DATA

[out] phKey

指向接收导入密钥句柄的 HCRYPTKEY 值的指针。 使用完密钥后,通过调用 CryptDestroyKey 函数释放句柄。

返回值

如果函数成功,则函数返回非零值。

如果函数失败,则返回零。 有关扩展的错误信息,请调用 GetLastError

以“NTE”开头的错误代码由使用的特定 CSP 生成。 下面是一些可能的错误代码。

返回代码 说明
ERROR_BUSY
如果在另一个线程或 进程 使用此密钥时将私钥导入到容器中,则某些 CSP 会设置此错误。
ERROR_INVALID_HANDLE
其中一个参数指定无效的句柄。
ERROR_INVALID_PARAMETER
其中一个参数包含无效的值。 这通常是无效的指针。
NTE_BAD_ALGID
要导入的 简单密钥 BLOB 未使用预期的 密钥交换算法进行加密。
NTE_BAD_DATA
此 CSP 不支持与要导入的公钥一起使用的算法,或者尝试导入使用公钥以外的其他内容加密的会话密钥。
NTE_BAD_FLAGS
指定的 dwFlags 参数无效。
NTE_BAD_TYPE
此 CSP 不支持密钥 BLOB 类型,可能无效。
NTE_BAD_UID
hProv 参数不包含有效的上下文句柄。
NTE_BAD_VER
密钥 BLOB 的版本号与 CSP 版本不匹配。 这通常表示需要升级 CSP。

注解

导入基于哈希的消息身份验证代码 (HMAC) 密钥时,调用方必须将导入的密钥标识为 PLAINTEXTKEYBLOB 类型,并在 PUBLICKEYSTRUC BLOB 标头的 aiKeyAlg 字段中设置相应的算法标识符。

CryptImportKey 函数可用于导入对称算法的纯文本密钥;但是,为方便使用,建议改用 CryptGenKey 函数。 导入纯文本密钥时,在 pbData 参数中传递的密钥 BLOB 的结构是 PLAINTEXTKEYBLOB

可以将 PLAINTEXTKEYBLOB 类型与使用中的 CSP 支持的任何算法或组合键类型一起使用。

有关导入纯文本键的示例,请参阅 示例 C 程序:导入纯文本键

以下示例演示如何设置标头字段。

keyBlob.header.bType = PLAINTEXTKEYBLOB;
keyBlob.header.bVersion = CUR_BLOB_VERSION;
keyBlob.header.reserved = 0;
// CALG_AES_128 is used as an example. You would set this to the 
// algorithm id that corresponds to the one used by the key.
keyBlob.header.aiKeyAlg = CALG_AES_128;

密钥的长度在 keyBlob.keyLength 中指定,后跟实际密钥数据。

注意 HMAC 算法没有自己的算法标识符;请改用 CALG_RC2。 CRYPT_IPSEC_HMAC_KEY 允许导入超过 16 个字节的 RC2 密钥。
 
对于任何 数据加密标准 (DES) 使用 PLAINTEXTKEYBLOB 的密钥排列,只能导入包括奇偶校验位在内的完整密钥大小。

支持以下密钥大小。

算法 支持的密钥大小
CALG_DES 64 位
CALG_3DES_112 128 位
CALG_3DES 192 位
 

示例

以下示例演示如何从密钥 BLOB 导入密钥。 有关此函数的完整示例,请参阅 示例 C 程序:对哈希进行签名和验证哈希签名。 有关使用此函数的其他代码,请参阅 示例 C 程序:解密文件

#include <windows.h>
#include <stdio.h>
#include <Wincrypt.h>

BOOL ImportKey(HCRYPTPROV hProv, LPBYTE pbKeyBlob, DWORD dwBlobLen)
{
    HCRYPTKEY hPubKey;

    //---------------------------------------------------------------
    // This code assumes that a cryptographic provider (hProv) 
    // has been acquired and that a key BLOB (pbKeyBlob) that is 
    // dwBlobLen bytes long has been acquired. 

    //---------------------------------------------------------------
    // Get the public key of the user who created the digital 
    // signature and import it into the CSP by using CryptImportKey. 
    // The key to be imported is in the buffer pbKeyBlob that is  
    // dwBlobLen bytes long. This function returns a handle to the 
    // public key in hPubKey.

    if(CryptImportKey(
        hProv,
        pbKeyBlob,
        dwBlobLen,
        0,
        0,
        &hPubKey))
    {
        printf("The key has been imported.\n");
    }
    else
    {
        printf("Public key import failed.\n");
        return FALSE;
    }

    //---------------------------------------------------------------
    // Insert code that uses the imported public key here.
    //---------------------------------------------------------------

    //---------------------------------------------------------------
    // When you have finished using the key, you must release it.
    if(CryptDestroyKey(hPubKey))
    {
        printf("The public key has been released.");
    }
    else
    {
        printf("The public key has not been released.");
        return FALSE;
    }

    return TRUE;
}

要求

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

另请参阅

CryptAcquireContext

CryptDestroyKey

CryptExportKey

密钥生成和交换函数