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 的类型而异:

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

[in] dwFlags

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

此参数可以是下列值之一。

价值 意义
CRYPT_EXPORTABLE
导入的密钥最终将重新导出。 如果未使用此标志,则调用 CryptExportKey 密钥句柄失败。
CRYPT_OAEP
此标志会导致在导入 SIMPLEBLOB时使用 RSA 加密和解密检查 PKCS #1 版本 2 格式。
CRYPT_NO_SALT
无盐值 为 40 位 对称密钥分配。 有关详细信息,请参阅 Salt Value 功能
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。

言论

导入 Hash-Based 消息身份验证代码(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 密钥。
 
对于使用 PLAINTEXTKEYBLOB的任何 数据加密标准(DES)密钥排列,只能导入完整密钥大小(包括奇偶校验位)。

支持以下密钥大小。

算法 支持的密钥大小
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 [仅限桌面应用]
目标平台 窗户
标头 wincrypt.h
Advapi32.lib
DLL Advapi32.dll

另请参阅

CryptAcquireContext

CryptDestroyKey

CryptExportKey

密钥生成和 Exchange 函数