Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> cryptoAPI в с++, функции CryptGenKey и CertOpenStore 
:(
    Опции темы
Arty007
Дата 28.11.2010, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ГоЛоВа



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 21.11.2010
Где: Odessa, Ukraine

Репутация: нет
Всего: нет



здравствуйте. есть два вопроса по cryptoAPI.
я знаю, что функция CryptGenKey может генерировать различные ключи, с её помощью я генерировал сессионные клюи для зашифровки сообщений, но мне теперь понадобилось сгенерировать пару открытый/закрытый ключ именно во время выполения программы, но я так и не могу понять как это сделать, если кто-то приведет код примера буду очень благодарен. и как потом отедльно вытащить открытый и закрытый ключ после генерации?
а второй вопрос заключаетсяя в том, что мне надо открыть харнилище сертификатов, вот пример кода:

Код

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <iostream>
#include <fstream>
using namespace std;
#define CERT_STORE_NAME  L"MY"
int main()
{
HCERTSTORE hStore;     

    if ( !( hStore = CertOpenStore(
    CERT_STORE_PROV_SYSTEM,
    0,
    NULL,
    CERT_SYSTEM_STORE_CURRENT_USER,
    CERT_STORE_NAME)))
    {
      puts("Нельзя открыть хранилище MY ");

    }
}


но выскакивает две ошибки в линковке:
Error 10 error LNK2019: unresolved external symbol __imp__CertOpenStore@20 referenced in function _main    123.obj    
Error 11 fatal error LNK1120: 1 unresolved externals    D:\123\Debug\123.exe
кто знает, что это может значить?
заранее благодарен.

Это сообщение отредактировал(а) Arty007 - 28.11.2010, 15:41
PM MAIL ICQ Skype   Вверх
Predator_2004
Дата 1.12.2010, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



попробуйте после инклудов
Код

#pragma comment(lib,"Crypt32.lib")

PM MAIL   Вверх
Arty007
Дата 4.12.2010, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ГоЛоВа



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 21.11.2010
Где: Odessa, Ukraine

Репутация: нет
Всего: нет



2Predator_2004, да, спасибо заработало, но теперь не могу перодолеть функцию CryptImportKey, выдает ошибку когдапытаюсь сессионный ключ расшифровать и привести его в вид HCRYPTKEY.


Вот полный код программы:
Код

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <iostream>
#include <fstream>
#pragma comment(lib,"Crypt32.lib")
using namespace std;
 
#define BLOCK_SIZE 10


char        SysMessage[512];
HCRYPTPROV  hProv = 0;
HCRYPTKEY   hKey  = 0;
HCRYPTKEY   hXchgKey  = 0;
BYTE        *pCryptBuf = 0;
HCERTSTORE  hStore = 0;  

HCRYPTKEY   hPubKey = 0;
HCRYPTKEY   hPrivateKey = 0;
 

#define MY_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

// Наименование персонального хранилища
#define CERT_STORE_NAME  L"MY"

// Наименование сертификата, установленного в это хранилище
#define SIGNER_NAME  L"Arty"

#define _szContainer "Public"

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


int main()
{
    char c;
    char        *pSrcData;
    BOOL        bRes;
    DWORD       buflen;
    DWORD       datalen;
 
    // Подключаемся к криптопровайдеру
    if(CryptAcquireContext(
            &hProv,                  // возвращаем ссылку на криптопровайдер
            (LPCWSTR)_szContainer,              
            MS_ENH_RSA_AES_PROV,            // Имя крипторовайдера   - MS_ENHANCED_PROV
            PROV_RSA_AES,             // Тип криптопровайдера ()     - PROV_RSA_FULL
            0 ))                     // никаких других действий
    {
        printf("A cryptographic context with the %s key container \n",_szContainer);
        printf("has been acquired.\n\n");
    }
    else
    {
        if (GetLastError() == NTE_BAD_KEYSET) //если была ошибка, то проврим, может контейнер с таким именем не существует
        {
            if(CryptAcquireContext(&hProv, (LPCWSTR)_szContainer, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) //если у криптопровайдера не существует контейнера с именем _szContainer, значит создадим его
            {
                printf("A new key container has been created.\n");
            }
            else
            {
                printf("Could not create a new key container.\n");
                getchar();
                exit(1);
            }
        }
        else
        {
            printf("A cryptographic service handle could not be acquired.\n");
            getchar();
            exit(1);
        }
          
    }
    //  Создаем сеансовый ключ
    if(!CryptGenKey(hProv,                            // AES крипторовайдер 
                    CALG_AES_256,                    // алгоритм CALG_AES_256 (CALG_RC2)
                    CRYPT_EXPORTABLE|CRYPT_ENCRYPT, //ключ можно экспортировать и им можно шифровать
                    &hKey ))
    {
        cout<<"CryptGenKey failed."<<endl;
        getchar();
        return -1;
    }

    // Устанавливаем режим шифрования сообщения (OFB - режим выходной обратной связи)
    /*DWORD dwMode = CRYPT_MODE_OFB;
    if(!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0)) 
    {
        printf("Error %x during CryptSetKeyParam!\n", GetLastError());
        getchar();
        return -1;
    }*/

    // generate key exchange key
    /*if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE|CRYPT_ENCRYPT, &hXchgKey ))
    {
        getchar();
        return -1;
    }*/


       
    // Открываем хранилище сертификатов
    if ( !( hStore = CertOpenStore(
            CERT_STORE_PROV_SYSTEM,
            0,
            NULL,
            CERT_SYSTEM_STORE_CURRENT_USER,
            CERT_STORE_NAME)))
    {
      puts("Ennable to open 'MY' ");
              getchar();
          return -1;
    }


    // Получаем указатель на наш сертификат
      PCCERT_CONTEXT pSignerCert = 0;; 
      //char* temp = new char[128];

      if(pSignerCert = CertFindCertificateInStore(
        hStore,
        MY_TYPE,
        0,
        CERT_FIND_SUBJECT_STR,
        SIGNER_NAME,
        NULL))
      {
        printf("Cert found\n");
      }
      else
      {
       
          printf( "Cert not found\n");
          getchar();
          return -1;
      }

      //Импортируем public key для шифрования сеансового ключа
        if(CryptImportPublicKeyInfo(
        hProv, 
        MY_TYPE, 
        &(pSignerCert->pCertInfo->SubjectPublicKeyInfo),
        &hPubKey))
      {
            printf("Import public key.\n");
      }
      else
      {
            printf("Ошибка CryptAcquireContext.");
            getchar();
            return -1;
      }




    BYTE *ppbKeyBlob; 
    DWORD dwBlobLength=0;
    ppbKeyBlob = NULL;

    //Определение размера BLOBа сессионного ключа
    if(CryptExportKey(  hKey,    
                        hPubKey ,
                        SIMPLEBLOB,
                        0,    
                        NULL, 
                        &dwBlobLength)) 
    {
        printf("Size of the BLOB for the public key determined. \n");
    }
    else
    {
        printf("Error computing BLOB length.\n");
        getchar();
        return -1;
    }

    // Распределение памяти для hKey.
    if(ppbKeyBlob = (LPBYTE)malloc(dwBlobLength)) 
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        printf("Out of memory. \n");
        getchar();
        return -1;
    }

    // Зашифрование сессионного ключа на ключе hPubKey, при экспорте сессионого ключа в "байты" информации.
    if(CryptExportKey(   
        hKey, 
        hPubKey ,
        SIMPLEBLOB,    
        0,    
        ppbKeyBlob,    
        &dwBlobLength))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        printf("Error exporting key.\n");
        free(ppbKeyBlob);
        ppbKeyBlob = NULL;
        getchar();
        return -1;
    }



    ///КРИПТАЦИЯ ФАЙЛА--------------------------------------
    FILE *in, *out;
    if( (in = fopen("D:\\TopSecret.txt","rb")) == NULL )
    //if( (in = fopen("D:\\Stuff\\Music\\am2pm_-_my_businnes.mp3","rb")) == NULL )
    {
        cout<<"Error in openning file for reading";
        getchar();
        return -1;
    }

    if( (out = fopen("D:\\out.crpt","w+b")) == NULL )
    {
        cout<<"Error in openning file for writing";
        getchar();
        return -1;
    }


    //Запись зашифрованного сессионного ключа в файл.
    if(fwrite(ppbKeyBlob, sizeof byte , dwBlobLength, out))
    {
        printf( "The session key has been written to the file\n" );
        free(ppbKeyBlob);
    }
    else
    {
        HandleError( "The session key could not be written to the file\n" );
    }


    // определяем размер буфера необходимого дя блоков длины BLOCK_SIZE
    buflen=BLOCK_SIZE;
    if(!CryptEncrypt( hKey,
                            0,          // no hash
                            TRUE,       // "final" flag
                            0,          // reserved
                            NULL,       // calculate buffer size only
                            &buflen,    // return size for ciphered text
                            0 ))
    {
        cout<<"CryptEncrypt (bufSize) failed."<<endl;
        getchar();
        return -1;
    }

    //выделяем память под буфер
    pCryptBuf = (BYTE*)malloc( buflen );
    
    bool check;
    int t=0;
    //непосредсвенно шифруем файл
    while((t=fread(pCryptBuf,sizeof byte,BLOCK_SIZE,in)))
    {
        datalen = t;
        check=feof(in);
        bRes = CryptEncrypt( hKey,  
                            0,          // no hash
                            TRUE,        // "final" flag
                            0,          // reserved
                            pCryptBuf,  // buffer with data
                            &datalen,   // return size for ciphered text
                            buflen );
        if( !bRes ) 
        {
            cout<<"CryptEncrypt (encryption) failed."<<endl;
            getchar();
            return -1;
        }

        fwrite(pCryptBuf,sizeof byte,datalen,out);

    }

    cout<<"File encryption completed successfully"<<endl;
    fclose(in);
    fclose(out);
    CryptDestroyKey(hKey);
    hKey = NULL;
    //ДЕКРИПТАЦИЯ-------------------------------------------------------------------------------
    if( (in = fopen("D:\\out.crpt","rb")) == NULL )
    {
        cout<<"Error in openning file for reading";
        getchar();
        return -1;
    }

    if( (out = fopen("D:\\decryptedOUT.txt","w+b")) == NULL )
    {
        cout<<"Error in openning file for writing";
        getchar();
        return -1;
    }

    //выделяем память под BLOB сессионного ключа
    if(ppbKeyBlob = (LPBYTE)malloc(dwBlobLength)) 
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        printf("Out of memory. \n");
        getchar();
        return -1;
    }
    //считываем BLOB сессионного ключа из зашифрованного файла
    if(fread(ppbKeyBlob, sizeof byte , dwBlobLength, in))
    {
        printf( "The session key has been read\n" );
    }
    else
    {
        HandleError( "The session key could not be read from the file\n" );
    }


    HCRYPTPROV hNextProv = 0;
    DWORD keySpec = 0;


    // извлекаем из сертификата контекст приватного ключа
    if(!CryptAcquireCertificatePrivateKey(pSignerCert,0,0,&hNextProv,&keySpec,0))
        {cout<<"Error getting private context\n";getchar();return -1;}
    //из которого собственно и добывается сам ключ
    if(!CryptGetUserKey(hNextProv,keySpec,&hPrivateKey))
        {cout<<"Error getting private key\n";getchar();return -1;}




    //импортируем BLOB сессионного ключа, непосредственно в сам ключ, расшифровывая его ключем hPrivateKey
    // ТУТ ОШИБКА ?????
    if(CryptImportKey(
        hNextProv,
        ppbKeyBlob,
        dwBlobLength,
        hPrivateKey,
        0,
        &hKey))
    {
        printf("The key has been imported.\n");
        CryptDestroyKey(hXchgKey);
    }
    else
    {
        printf("Public key import failed.\n");
        return FALSE;
    }



    // определяем размер буфера необходимого дя блоков длины BLOCK_SIZE
    buflen=BLOCK_SIZE;    
    bRes = CryptEncrypt( hKey,
                            0,          // no hash
                            TRUE,       // "final" flag
                            0,          // reserved
                            NULL,       // calculate buffer size only
                            &buflen,    // return size for ciphered text
                            0 );
    datalen=buflen;
    //выделяем память под буфер
    pCryptBuf = (BYTE*)malloc( buflen );

    //непосредсвенно расшифровываем фал
    while((t=fread(pCryptBuf,sizeof byte,datalen,in)))
    {

        //datalen = t;
        buflen = t;
        check=feof(in);
        //Decrypt back
        bRes = CryptDecrypt( hKey,
                        0,
                        TRUE,
                        0, 
                        pCryptBuf,
                        &buflen );

        if( !bRes ) 
        {
            cout<<"CryptEncrypt (buffer size) failed."<<endl;
            getchar();
            return -1;
        }

        fwrite(pCryptBuf,sizeof byte,buflen,out);

    }



    cout<<"File decryption completed successfully"<<endl;
    fclose(in);
    fclose(out);
    CryptDestroyKey(hKey);
    if (CryptReleaseContext(hProv,0))
    {
        printf("The handle has been released.\n");
    }
    else
    {
        printf("The handle could not be released.\n");
    }



    getchar();

}



в чем может быть ошибка??
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0480 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.