CryptExportKey 函式 (wincrypt.h)

重要 此 API 已被取代。 新的和現有的軟體應該開始使用 密碼編譯新一代 API。 Microsoft 可能會在未來的版本中移除此 API。
 
CryptExportKey 函式會以安全的方式,從密碼編譯服務提供者導出密碼編譯密鑰或密鑰組, (CSP) 。

要匯出之金鑰的句柄會傳遞至函式,而函式會傳回 密鑰 BLOB。 此密鑰 BLOB 可以透過不安全的傳輸傳送,或儲存在不安全的儲存位置。 此函式可以匯出 安全 通道會話金鑰、一般 會話密鑰公鑰公開/私鑰組。 在預期的收件者使用 CryptImportKey 函式將密鑰或金鑰組匯入收件者的 CSP 之前,要導出的密鑰 BLOB 是無用的。

語法

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。 hExpKeyhKey 都必須來自相同的 CSP。

通常,這是目的地使用者的 金鑰交換公鑰 。 不過,某些 CSP 中的某些通訊協定需要有屬於目的地使用者的會話密鑰才能用於此用途。

如果 dwBlobType 指定的金鑰 BLOB 類型為 PUBLICKEYBLOB,則此參數未使用,且必須設定為零。

如果 dwBlobType 所指定的金鑰 BLOB 類型為 PRIVATEKEYBLOB,這通常是用來加密金鑰 BLOB 的工作階段金鑰句柄。 某些 CSP 允許此參數為零,在此情況下,應用程式必須手動加密 私鑰 BLOB ,才能保護它。

若要判斷 Microsoft 密碼編譯服務提供者如何回應此參數,請參閱 Microsoft 密碼編譯服務提供者私鑰 BLOB 小節。

注意 某些 CSP 可能會因為作業而修改此參數。 後續將此金鑰用於其他用途的應用程式應該呼叫 CryptDuplicateKey 函式,以建立重複的密鑰句柄。 當應用程式使用句柄完成時,請呼叫 CryptDestroyKey 函式來釋放它。
 

[in] dwBlobType

指定要在 pbData 中匯出的金鑰 BLOB 類型。 這必須是下列其中一個常數,如 密碼編譯密鑰記憶體和 Exchange 中所述。

意義
OPAQUEKEYBLOB
用來以 Schannel CSP 或任何其他廠商特定格式儲存會話密鑰。 OPAQUEKEYBLOB 不可轉譯,而且必須在產生 BLOB 的 CSP 內使用。
PRIVATEKEYBLOB
用來傳輸 公用/私鑰組
PUBLICKEYBLOB
用來傳輸公鑰。
SIMPLEBLOB
用來傳輸會話金鑰。
PLAINTEXTKEYBLOB
PLAINTEXTKEYBLOB,用來匯出使用中 CSP 支援的任何密鑰。
SYMMETRICWRAPKEYBLOB
用來匯出和匯入以另一個 對稱密鑰包裝的對稱密鑰 。 實際包裝的索引鍵格式是IETF RFC 3217 標準中指定的格式。

[in] dwFlags

指定函式的其他選項。 此參數可以是零或下列一或多個值的組合。

意義
CRYPT_BLOB_VER3
0x00000080
此旗標會使此函式匯出 BLOB 類型的第 3 版。
CRYPT_DESTROYKEY
0x00000004
此旗標會終結 OPAQUEKEYBLOB 中的原始密鑰。 此旗標僅適用於 Schannel CSP。
CRYPT_OAEP
0x00000040
此旗標會在匯出 SIMPLEBLOB 時,使用 RSA 加密和解密建立 PKCS #1 第 2 版格式設定。
CRYPT_SSL2_FALLBACK
0x00000002
RSA 加密區塊 填補 的前八個字節必須設定為0x03,而不是隨機數據。 這可防止版本復原攻擊,並在 SSL3 規格中討論。 此旗標僅適用於 Schannel CSP。
CRYPT_Y_ONLY
0x00000001
未使用此旗標。

[out] pbData

接收 金鑰 BLOB 資料的緩衝區指標。 此 BLOB 的格式會根據 dwBlobType 參數中要求的 BLOB 類型而有所不同。 如需 PRIVATEKEYBLOB、PUBLICKEYBLOB 和 SIMPLEBLOB 的格式,請參閱 基底提供者密鑰 BLOB

如果此參數為 NULL,必要的緩衝區大小會放在 pdwDataLen 參數所指向的值中。 如需詳細資訊,請參閱 擷取未知長度的數據

[in, out] pdwDataLen

在專案上, DWORD 值的指標包含 pbData 參數所指向之緩衝區的大小,以位元組為單位。 當函式傳回時,這個值會包含儲存在緩衝區中的位元元組數目。

注意 處理緩衝區中傳回的數據時,應用程式必須使用傳回之數據的實際大小。 實際大小可能比輸入上指定的緩衝區大小稍微小一點。 在輸入上,緩衝區大小通常會指定夠大,以確保最大可能的輸出數據符合緩衝區。 在輸出上,此參數所指向的變數會更新,以反映複製到緩衝區的數據實際大小。
 
若要擷取 pbData 緩衝區的必要大小,請傳遞 pbDataNULL。 必要的緩衝區大小將會放在此參數所指向的值中。

傳回值

如果函式成功,函式會傳回非零 (TRUE) 。

如果函式失敗,它會傳回零 (FALSE) 。 如需擴充錯誤資訊,請呼叫 GetLastError

由 「NTE」 開頭的錯誤碼是由所使用的特定 CSP 所產生。 下表顯示一些可能的錯誤碼。

傳回碼 Description
ERROR_INVALID_HANDLE
其中一個參數指定無效的句柄。
ERROR_INVALID_PARAMETER
其中一個參數包含無效的值。 這通常是無效的指標。
ERROR_MORE_DATA
如果 pbData 參數指定的緩衝區不足以保存傳回的數據,函式會設定ERROR_MORE_DATA程序代碼,並以位元組為單位儲存 pdwDataLen 所指向的變數中所需的緩衝區大小。
NTE_BAD_DATA
此 CSP 不支援與要匯出之公鑰搭配使用的演算法,或嘗試匯出使用您其中一個公鑰以外的專案加密的會話金鑰。
NTE_BAD_FLAGS
dwFlags 參數為非零。
NTE_BAD_KEY
hKeyhExpKey 指定的一或兩個金鑰無效。
NTE_BAD_KEY_STATE
您沒有匯出金鑰的許可權。 也就是說,建立 hKey 金鑰時,未指定CRYPT_EXPORTABLE旗標。
NTE_BAD_PUBLIC_KEY
dwBlobType 指定的密鑰 BLOB 類型是 PUBLICKEYBLOB,但 hExpKey 不包含公鑰句柄。
NTE_BAD_TYPE
dwBlobType 參數會指定未知的 BLOB 類型。
NTE_BAD_UID
找不到建立 hKey 金鑰時所指定的 CSP 內容。
NTE_NO_KEY
正在匯出會話密鑰,而 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
程式庫 Advapi32.lib
Dll Advapi32.dll

另請參閱

CryptImportKey

金鑰產生和 Exchange 函式