ГоЛоВа
Профиль
Группа: Участник
Сообщений: 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();
}
|
в чем может быть ошибка??
|