2014-12-10 5 views
0

몇 가지 문제가 있습니다. CryptoAPI를 사용하여 대칭 키를 생성하고 내 보내야합니다.수출 대법 AES 키 cryptoapi

 if(CryptAcquireContext(&hCryptProv_AES, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) 
    { 
     _tprintf(
      TEXT("A cryptographic provider has been acquired. \n")); 
    } 
    else 
    { 
      DWORD d = GetLastError(); 
      std::cout<<""; 
      return -1; 
    } 

    if (!CryptGenKey(hCryptProv_AES,CALG_AES_256,CRYPT_EXPORTABLE,&hSessionKey_AES)) 
     { 
      DWORD d = GetLastError(); 
      std::cout<<""; 
      return -1; 
     } 
    else 
    { 
     std::cout<<"OK"; 
    } 

    // Export key 
    BYTE keybuf[ 1024 ], buffer[ 1024 ]; 
    DWORD i, keylen = sizeof(buffer); 

    struct ekb 
    { 
     PUBLICKEYSTRUC hdr; 
     ALG_ID     algId; 
     BYTE     key[1]; 
    } *encKey = (struct ekb *)buffer; 

    bool bbb = CryptExportKey(hSessionKey_AES, NULL, SIMPLEBLOB, 0, (BYTE *)encKey, &keylen); 
    DWORD f = GetLastError(); 

그러나 AES 키를 사용할 수는 없습니다. 어떻게이 문제를 해결할 수 있습니까? 나는 어떻게 AES 열쇠를 얻을 수 있는가 ??

업데이트 예를 들어 다음 코드를 사용하고 공용 RSA 키를 가져올 수 있습니다. 수출 후

char * base_txt = "Test text"; 
    char * enc_text = ""; 


    if(CryptAcquireContext(&hCryptProv_RSA, NULL, MS_ENHANCED_PROV , PROV_RSA_FULL, 0)) 
    { 
     _tprintf(
      TEXT("A cryptographic provider has been acquired. \n")); 
    } 
    else 
    { 
      DWORD d = GetLastError(); 
      std::cout<<""; 
      return -1; 
    } 

    if (!CryptGenKey(hCryptProv_RSA,AT_KEYEXCHANGE,1024<<16,&hSessionKey)) 
     { 
      DWORD d = GetLastError(); 
      std::cout<<""; 
      return -1; 
     } 

    RSAPubKey1024 key; 
    DWORD dwLen=sizeof(RSAPubKey1024); 



    // Export key 
    bool bb = CryptExportKey(hSessionKey,NULL,PUBLICKEYBLOB,0,(BYTE *)&key,&dwLen); 

업데이트 2 나는 키 가져 오기 및 암호화하고

HCRYPTPROV hCryptProv_AES22; 
    if (CryptAcquireContext(&hCryptProv_AES22, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) 
    { 
     printf("A cryptographic provider has been acquired.\r\n"); 
    } 
    else 
    { 
     DWORD d = GetLastError(); 
     return -1; 
    } 
    int iii = CryptImportKey(hCryptProv_AES22,(BYTE *)&exportKey_AES,keylen,NULL,NULL,&hSessionKey_AES2); 

    if(CryptSetKeyParam(hSessionKey_AES2,KP_IV, exportKey_AES, 0)) 
    { 
     BYTE encryptedMessage[1024]; 
     const char * message = "Decryption Works -- using multiple blocks"; 
     BYTE messageLen = (BYTE)strlen(message); 
     memcpy(encryptedMessage, message, messageLen); 
     DWORD encryptedMessageLen = messageLen; 
     CryptEncrypt(hSessionKey_AES2, NULL, TRUE, 0, encryptedMessage, &encryptedMessageLen, sizeof(encryptedMessage));  
     CryptDecrypt(hSessionKey_AES2,NULL,TRUE,0,encryptedMessage, &encryptedMessageLen); 

    } 
+0

왜 AES 키를 걸 수 없다고 생각하십니까? 'CryptExportKey'는'FALSE'를 리턴합니까? 그렇다면'GetLastError'는 어떤 에러 코드를 제공합니까? – Vitaliy

+0

반환 값 FALSE && 오류 코드 f = 2148073485 – Vahagn

답변

1

CryptExportKey는 한계가있다 해독하려고합니다. 은 비공개 키를 암호화 된 형식으로 내보내려면이 필요합니다. 공용 부분 또는 RSA 키 쌍을 내보낼 때 두 번째 CryptExportKey 매개 변수를 NULL으로 만들고 키를 암호화되지 않은 형식으로 내보내도됩니다. 그러나 이 0이 아닌 hExpKey 매개 변수를 지정해야하는 대칭 키에 대해 동일한 작업을 수행 할 수 없습니다.

#include <Windows.h> 
#include <cstdio> 

int main(int argc, char *argv[]) 
{ 
    // Create AES key 
    HCRYPTPROV hCryptProv_AES; 
    if (CryptAcquireContext(&hCryptProv_AES, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) 
    { 
     printf("A cryptographic provider has been acquired.\r\n"); 
    } 
    else 
    { 
     DWORD d = GetLastError(); 
     return -1; 
    } 
    HCRYPTKEY hSessionKey_AES; 
    if (!CryptGenKey(hCryptProv_AES, CALG_AES_256, CRYPT_EXPORTABLE, &hSessionKey_AES)) 
    { 
     DWORD d = GetLastError(); 
     return -1; 
    } 
    // Create RSA key to encrypt AES one 
    HCRYPTKEY hSessionKey; 
    if (!CryptGenKey(hCryptProv_AES, AT_KEYEXCHANGE, 1024 << 16, &hSessionKey)) 
    { 
     DWORD d = GetLastError(); 
     return -1; 
    } 
    // Export key 
    DWORD keylen; 
    BOOL ok = CryptExportKey(hSessionKey_AES, hSessionKey, SIMPLEBLOB, 0, NULL, &keylen); 
    if (ok == FALSE) 
    { 
     DWORD d = GetLastError(); 
     return -1; 
    } 
    BYTE *encKey = (BYTE *)malloc(keylen); 
    ok = CryptExportKey(hSessionKey_AES, hSessionKey, SIMPLEBLOB, 0, encKey, &keylen); 
    if (ok == FALSE) 
    { 
     DWORD d = GetLastError(); 
     return -1; 
    } 
    else 
     printf("A cryptographic key export succeeded.\r\n"); 
    return 0; 
} 

당신이 (당신이 앨리스는 밥 그녀의 AES 키에 보내 원한다면, 말할 수) 키 교환을 수행 할 경우, 다음을 수행해야합니다 : 당신이 hExpKey 매개 변수를 지정하는 경우, 코드가 작동 는, 예 참조 단계 :

  1. Bob은 RSA 키를 생성하고 공용 부분을 Alice에 보냅니다. 봐, 밥 시작, 앨리스가 아니야!
  2. Bob이 주요 공개 부분을 Alice에게 보냅니다.
  3. Alice가 AES 키를 생성합니다.
  4. Alice는 Bob의 공개 키로 AES 키를 암호화합니다.
  5. Alice가 Bob에게 AES 키를 보냅니다.
  6. Bob은 자신의 개인 키를 사용하여 AES 키를 해독합니다 (즉, CryptImportKey으로 가져 오기). 키를 가져올 때 hPubKey 매개 변수를 NULL이 아닌 값으로 설정하면 실제로 Bob의 키 핸들로 설정됩니다. 그렇지 않으면 AES 키가 암호화되므로 가져 오기가 실패합니다.
+0

괜찮지 만 가져 오기를 원하는 곳은 int iii = CryptImportKey (hCryptProv_AES, (BYTE *) 및 exportKey_AES, keylen, NULL, NULL, NULL 및 new_session_key)입니다. ? – Vahagn

+0

답변에 대한 키 교환 방법에 대한 설명을 추가했습니다. – Vitaliy

+0

좋은, 고마워, 내가 고칠 그것을 시도 :) 감사합니다 !!! – Vahagn