CryptExportKey 함수(wincrypt.h)

중요 이 API는 더 이상 사용되지 않습니다. 신규 및 기존 소프트웨어는 Cryptography Next Generation API 사용을 시작해야 합니다. Microsoft는 향후 릴리스에서 이 API를 제거할 수 있습니다.
 
CryptExportKey 함수는 CSP(암호화 서비스 공급자)에서 암호화 또는 키 쌍을 안전한 방식으로 내보냅니다.

내보낼 키에 대한 핸들이 함수에 전달되고 함수는 키 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을 사용할 수 있습니다. hExpKeyhKey는 모두 동일한 CSP에서 와야 합니다.

대부분의 경우 대상 사용자의 키 교환 공개 키 입니다. 그러나 일부 CSP의 특정 프로토콜에서는 대상 사용자에 속하는 세션 키를 이 용도로 사용해야 합니다.

dwBlobType에 지정된 키 BLOB 형식이 PUBLICKEYBLOB인 경우 이 매개 변수는 사용되지 않으며 0으로 설정해야 합니다.

dwBlobType에 지정된 키 BLOB 형식이 PRIVATEKEYBLOB인 경우 일반적으로 키 BLOB을 암호화하는 데 사용되는 세션 키에 대한 핸들입니다. 일부 CSP는 이 매개 변수를 0으로 허용합니다. 이 경우 애플리케이션은 프라이빗 키 BLOB 을 수동으로 암호화하여 보호해야 합니다.

Microsoft 암호화 서비스 공급자가 이 매개 변수에 응답하는 방법을 확인하려면 Microsoft 암호화 서비스 공급자프라이빗 키 BLOB 섹션을 참조하세요.

참고 일부 CSP는 작업의 결과로 이 매개 변수를 수정할 수 있습니다. 이후에 다른 용도로 이 키를 사용하는 애플리케이션은 CryptDuplicateKey 함수를 호출하여 중복 키 핸들을 만들어야 합니다. 애플리케이션이 핸들 사용을 마쳤으면 CryptDestroyKey 함수를 호출하여 해제합니다.
 

[in] dwBlobType

pbData에서 내보낼 키 BLOB의 형식을 지정합니다. 암호화 키 스토리지 및 Exchange에서 설명한 대로 다음 상수 중 하나여야 합니다.

의미
OPAQUEKEYBLOB
세션 키를 Schannel CSP 또는 다른 공급업체별 형식으로 저장하는 데 사용됩니다. OPAQUEKEYBLOB은 변환할 수 없으며 BLOB을 생성한 CSP 내에서 사용해야 합니다.
PRIVATEKEYBLOB
퍼블릭/프라이빗 키 쌍을 전송하는 데 사용됩니다.
PUBLICKEYBLOB
공용 키를 전송하는 데 사용됩니다.
SIMPLEBLOB
세션 키를 전송하는 데 사용됩니다.
PLAINTEXTKEYBLOB
사용 중인 CSP에서 지원하는 키를 내보내는 데 사용되는 PLAINTEXTKEYBLOB 입니다.
SYMMETRICWRAPKEYBLOB
다른 대칭 키로 래핑된 대칭 키를 내보내고 가져오는 데 사용됩니다. 실제 래핑된 키는 IETF RFC 3217 표준에 지정된 형식입니다.

[in] dwFlags

함수에 대한 추가 옵션을 지정합니다. 이 매개 변수는 0이거나 다음 값 중 하나 이상의 조합일 수 있습니다.

의미
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 암호화 블록 패딩 의 처음 8바이트는 임의 데이터가 아닌 0x03 설정해야 합니다. 이렇게 하면 버전 롤백 공격을 방지하고 SSL3 사양에서 설명합니다. 이 플래그는 Schannel CSP에만 사용할 수 있습니다.
CRYPT_Y_ONLY
0x00000001
이 플래그는 사용되지 않습니다.

[out] pbData

키 BLOB 데이터를 수신하는 버퍼에 대한 포인터입니다. 이 BLOB의 형식은 dwBlobType 매개 변수에서 요청된 BLOB 형식에 따라 달라집니다. PRIVATEKEYBLOB, PUBLICKEYBLOB 및 SIMPLEBLOB에 대한 형식은 기본 공급자 키 BLOB을 참조하세요.

이 매개 변수가 NULL이면 pdwDataLen 매개 변수가 가리키는 값에 필요한 버퍼 크기가 배치됩니다. 자세한 내용은 알 수 없는 길이의 데이터 검색을 참조하세요.

[in, out] pdwDataLen

항목에서 pbData 매개 변수가 가리키는 버퍼의 크기(바이트)를 포함하는 DWORD 값에 대한 포인터입니다. 함수가 반환되면 이 값에는 버퍼에 저장된 바이트 수가 포함됩니다.

참고 버퍼에서 반환된 데이터를 처리할 때 애플리케이션은 반환된 데이터의 실제 크기를 사용해야 합니다. 실제 크기는 입력에 지정된 버퍼의 크기보다 약간 작을 수 있습니다. 입력에서 버퍼 크기는 일반적으로 가능한 가장 큰 출력 데이터가 버퍼에 맞도록 충분히 크게 지정됩니다. 출력에서 이 매개 변수가 가리키는 변수는 버퍼에 복사된 데이터의 실제 크기를 반영하도록 업데이트됩니다.
 
pbData 버퍼의 필요한 크기를 검색하려면 pbData대해 NULL을 전달합니다. 필요한 버퍼 크기는 이 매개 변수가 가리키는 값에 배치됩니다.

반환 값

함수가 성공하면 함수는 0이 아닌 값(TRUE)을 반환합니다.

함수가 실패하면 0(FALSE)을 반환합니다. 확장 오류 정보는 GetLastError를 호출합니다.

"NTE"가 앞에 있는 오류 코드는 사용 중인 특정 CSP에 의해 생성됩니다. 다음 표에서는 몇 가지 가능한 오류 코드를 보여 줍니다.

반환 코드 설명
ERROR_INVALID_HANDLE
매개 변수 중 하나는 유효하지 않은 핸들을 지정합니다.
ERROR_INVALID_PARAMETER
매개 변수 중 하나에 유효하지 않은 값이 포함되어 있습니다. 이는 가장 자주 유효하지 않은 포인터입니다.
ERROR_MORE_DATA
pbData 매개 변수로 지정된 버퍼가 반환된 데이터를 저장할 만큼 크지 않은 경우 함수는 ERROR_MORE_DATA 코드를 설정하고 pdwDataLen이 가리키는 변수에 필요한 버퍼 크기를 바이트 단위로 저장합니다.
NTE_BAD_DATA
내보낼 공개 키와 함께 작동하는 알고리즘은 이 CSP에서 지원되지 않거나 공개 키 중 하나 이외의 다른 항목으로 암호화된 세션 키를 내보내려고 했습니다.
NTE_BAD_FLAGS
dwFlags 매개 변수가 0이 아닌 경우
NTE_BAD_KEY
hKey 및 hExpKey로 지정된 키 중 하나 또는 둘 다 잘못되었습니다.
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 함수