Статус: Активный участник
Группы: Участники
Зарегистрирован: 13.06.2013(UTC) Сообщений: 83 Откуда: Москва Сказал(а) «Спасибо»: 16 раз Поблагодарили: 1 раз в 1 постах
|
Для полноты, привожу также готовый пример на импорт. Здесь, если '#if 1', то импортируем сессионный ключ (hSessionkey) на ключе, который подлежал диверсификации (hKey), если '#if 0', то импортируем сессионный ключ (hSessionkey) на дивключе (hDivKey). Цитата: // Настоящий файл может использоваться только в целях обучения // #include <stdio.h> #ifdef _WIN32 # include <windows.h> # include <wincrypt.h> # include <WinCryptEx.h> #else # include <string.h> # include <stdlib.h> # include <ctype.h> # include <unistd.h> # include <CSP_WinDef.h> # include <CSP_WinCrypt.h> # include <WinCryptEx.h> #endif
#ifdef _WIN32 #pragma warning( push ) #pragma warning( disable : 4996 ) #endif
#ifdef _WIN32 #define TEMP_CONTAINER_NAME "\\\\.\\REGISTRY\\tmp_cont" #else #define TEMP_CONTAINER_NAME "\\\\.\\hdimage\\tmp_cont" #endif
#define DIV_DATA_SZ 32
int main(int argc, char *argv[]) { BYTE PIN_TO_CONT[]={'1','1','1','1','1','1','1','1','\0'}; HCRYPTPROV hProv = 0; HCRYPTKEY hKey = 0; HCRYPTKEY hDivKey = 0; HCRYPTKEY hSessionKey = 0; BYTE blob[sizeof(CRYPT_DIVERSBLOB)+DIV_DATA_SZ]; CRYPT_DIVERSBLOB * Blob = (CRYPT_DIVERSBLOB*)blob; DWORD dwTmp; BYTE div_data[DIV_DATA_SZ]={ 0,1,2,3,4,5,6,7, 0,1,2,3,4,5,6,7, 0,1,2,3,4,5,6,7, 0,1,2,3,4,5,6,7};
BYTE *pbKeyBlobSimple = NULL; DWORD dwBlobLenSimple; BYTE iv[SEANCE_VECTOR_LEN]; BYTE dt[G28147_KEYLEN]; BYTE im[EXPORT_IMIT_SIZE]; BYTE im2[EXPORT_IMIT_SIZE]; HCRYPTHASH hHash = 0; BYTE data[G28147_KEYLEN]; DWORD datasz=G28147_KEYLEN; BYTE pbSessionKeyEncrypted[G28147_KEYLEN]; //зашифрованный на мастере сессионный ключ BYTE pbSessionKeyImit[EXPORT_IMIT_SIZE]; //имитовскавка по незашифрованному сессионному ключу BYTE ASNstrSmpl[11] = {0x30,0x09,0x06,0x07,0x2A,0x85,0x03,0x02,0x02,0x1F,0x01}; BYTE blob2[sizeof(CRYPT_SIMPLEBLOB)+sizeof(ASNstrSmpl)]; CRYPT_SIMPLEBLOB *Blob2 = (CRYPT_SIMPLEBLOB*)blob2;
//создаем ключ (hKey), на основе которого впоследствии получим дивключ if(CryptAcquireContext( &hProv, TEMP_CONTAINER_NAME, NULL, PROV_GOST_2001_DH, 0) ) { CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, PIN_TO_CONT, 0); } else { if(!CryptAcquireContext( &hProv, TEMP_CONTAINER_NAME, NULL, PROV_GOST_2001_DH, CRYPT_NEWKEYSET) ) { printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, PIN_TO_CONT, 0); } if(!CryptGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hKey)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); }
//диверсифицируем hKey, получаем hDivKey Blob->DiversBlobHeader.BlobHeader.bType = DIVERSKEYBLOB; Blob->DiversBlobHeader.BlobHeader.bVersion = BLOB_VERSION; Blob->DiversBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147; Blob->DiversBlobHeader.aiDiversAlgId = CALG_PRO_DIVERS; Blob->DiversBlobHeader.dwDiversMagic = DIVERS_MAGIC; Blob->DiversBlobHeader.cbDiversData = DIV_DATA_SZ; CopyMemory((LPBYTE)Blob->bDiversData,div_data,DIV_DATA_SZ); if(!CryptImportKey(hProv, blob, sizeof(CRYPT_DIVERSBLOB)+DIV_DATA_SZ, hKey, CRYPT_EXPORTABLE, &hDivKey)) { printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); }
//генерим сессионный if(!CryptGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hSessionKey)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } //экспорт сессионного на ключе, который диверсифицировали (hKey) dwTmp = CALG_SIMPLE_EXPORT; if(!CryptSetKeyParam(hKey, KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = CRYPT_MODE_ECB; if(!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = ZERO_PADDING; if(!CryptSetKeyParam(hKey, KP_PADDING, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } memset(iv,0,SEANCE_VECTOR_LEN); if(!CryptSetKeyParam(hKey, KP_IV, iv, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(!CryptExportKey(hSessionKey, hKey, SIMPLEBLOB, 0, NULL, &dwBlobLenSimple)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } pbKeyBlobSimple = (BYTE*)malloc(dwBlobLenSimple); if(!pbKeyBlobSimple){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(!CryptExportKey(hSessionKey, hKey, SIMPLEBLOB, 0, pbKeyBlobSimple, &dwBlobLenSimple)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } memcpy(dt,&pbKeyBlobSimple[sizeof(CRYPT_SIMPLEBLOB_HEADER)+SEANCE_VECTOR_LEN],G28147_KEYLEN); memcpy(im,&pbKeyBlobSimple[sizeof(CRYPT_SIMPLEBLOB_HEADER)+SEANCE_VECTOR_LEN+G28147_KEYLEN],EXPORT_IMIT_SIZE); free(pbKeyBlobSimple); //и сразу расшифровываем на том же ключе (нам нужно будет значение сессионного в открытом виде, когда мы будем руками формировать криптограмму по нему) dwTmp = CALG_G28147; if(!CryptSetKeyParam(hKey , KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = G28147_KEYLEN; if(!CryptDecrypt(hKey, 0, TRUE, 0, dt, &dwTmp)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } //проверяем, правильно ли расшифровался сессионный if(!CryptCreateHash(hProv, CALG_G28147_IMIT, hKey, 0, &hHash)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = G28147_KEYLEN; if(!CryptHashData(hHash, dt, dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = EXPORT_IMIT_SIZE; if(!CryptGetHashParam(hHash, HP_HASHVAL, NULL, &dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(dwTmp != EXPORT_IMIT_SIZE){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(!CryptGetHashParam(hHash, HP_HASHVAL, im2, &dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(memcmp(im,im2,EXPORT_IMIT_SIZE)!=0){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(hHash)CryptDestroyHash(hHash); #if 1 //сформируем (руками) криптограмму сессионного на hKey //копируем, нам еще пригодится сессионный в открытолм виде memcpy(data,dt,G28147_KEYLEN); memset(iv,0,SEANCE_VECTOR_LEN); if(!CryptSetKeyParam(hKey, KP_IV, iv, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = CRYPT_SIMPLEMIX_MODE; if(!CryptSetKeyParam(hKey, KP_MIXMODE, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(!CryptEncrypt(hKey, 0, TRUE, 0, data, &datasz, datasz)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } memcpy(pbSessionKeyEncrypted,data,datasz); memcpy(data,dt,G28147_KEYLEN); if(!CryptCreateHash(hProv, CALG_G28147_IMIT, hKey, 0, &hHash)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = G28147_KEYLEN; if(!CryptHashData(hHash, data, dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = EXPORT_IMIT_SIZE; if(!CryptGetHashParam(hHash, HP_HASHVAL, NULL, &dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(dwTmp != EXPORT_IMIT_SIZE){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(!CryptGetHashParam(hHash, HP_HASHVAL, data, &dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } memcpy(pbSessionKeyImit,data,dwTmp); if(hHash)CryptDestroyHash(hHash); //импортируем криптограмму сессиолнного dwTmp = CALG_SIMPLE_EXPORT; if(!CryptSetKeyParam(hKey, KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } Blob2->tSimpleBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147; Blob2->tSimpleBlobHeader.BlobHeader.bType = SIMPLEBLOB; Blob2->tSimpleBlobHeader.BlobHeader.bVersion = BLOB_VERSION; Blob2->tSimpleBlobHeader.BlobHeader.reserved = 0; Blob2->tSimpleBlobHeader.EncryptKeyAlgId = CALG_G28147; Blob2->tSimpleBlobHeader.Magic = G28147_MAGIC; memset(Blob2->bSV, 0, SEANCE_VECTOR_LEN); memcpy(Blob2->bEncryptionParamSet, ASNstrSmpl, sizeof(ASNstrSmpl)); memcpy(Blob2->bEncryptedKey, pbSessionKeyEncrypted, G28147_KEYLEN); memcpy(Blob2->bMacKey, pbSessionKeyImit, EXPORT_IMIT_SIZE); if(!CryptImportKey( hProv, blob2, sizeof(CRYPT_SIMPLEBLOB)+sizeof(ASNstrSmpl), hKey, 0,//CRYPT_EXPORTABLE, &hSessionKey) ) { printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } #else //сформируем (руками) криптограмму сессионного на hDivKey //копируем, нам еще пригодится сессионный в открытолм виде memcpy(data,dt,G28147_KEYLEN); dwTmp = CALG_G28147; if(!CryptSetKeyParam(hDivKey , KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = CRYPT_MODE_ECB; if(!CryptSetKeyParam(hDivKey, KP_MODE, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = ZERO_PADDING; if(!CryptSetKeyParam(hDivKey, KP_PADDING, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } memset(iv,0,SEANCE_VECTOR_LEN); if(!CryptSetKeyParam(hDivKey, KP_IV, iv, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = CRYPT_SIMPLEMIX_MODE; if(!CryptSetKeyParam(hDivKey, KP_MIXMODE, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(!CryptEncrypt(hDivKey, 0, TRUE, 0, data, &datasz, datasz)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } memcpy(pbSessionKeyEncrypted,data,datasz); memcpy(data,dt,G28147_KEYLEN); if(!CryptCreateHash(hProv, CALG_G28147_IMIT, hDivKey, 0, &hHash)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = G28147_KEYLEN; if(!CryptHashData(hHash, data, dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } dwTmp = EXPORT_IMIT_SIZE; if(!CryptGetHashParam(hHash, HP_HASHVAL, NULL, &dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(dwTmp != EXPORT_IMIT_SIZE){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } if(!CryptGetHashParam(hHash, HP_HASHVAL, data, &dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } memcpy(pbSessionKeyImit,data,dwTmp); if(hHash)CryptDestroyHash(hHash); //импортируем криптограмму сессиолнного dwTmp = CALG_SIMPLE_EXPORT; if(!CryptSetKeyParam(hDivKey, KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } Blob2->tSimpleBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147; Blob2->tSimpleBlobHeader.BlobHeader.bType = SIMPLEBLOB; Blob2->tSimpleBlobHeader.BlobHeader.bVersion = BLOB_VERSION; Blob2->tSimpleBlobHeader.BlobHeader.reserved = 0; Blob2->tSimpleBlobHeader.EncryptKeyAlgId = CALG_G28147; Blob2->tSimpleBlobHeader.Magic = G28147_MAGIC; memset(Blob2->bSV, 0, SEANCE_VECTOR_LEN); memcpy(Blob2->bEncryptionParamSet, ASNstrSmpl, sizeof(ASNstrSmpl)); memcpy(Blob2->bEncryptedKey, pbSessionKeyEncrypted, G28147_KEYLEN); memcpy(Blob2->bMacKey, pbSessionKeyImit, EXPORT_IMIT_SIZE); if(!CryptImportKey( hProv, blob2, sizeof(CRYPT_SIMPLEBLOB)+sizeof(ASNstrSmpl), hDivKey, 0,//CRYPT_EXPORTABLE, &hSessionKey) ) { printf("[%s, %s, %d] : error 0x%x\n",__FILE__,__FUNCTION__,__LINE__,GetLastError()); exit(1); } #endif }
#ifdef _WIN32 #pragma warning( pop ) #endif
При '#if 1' - работает При '#if 0' - нет. Отредактировано пользователем 13 мая 2015 г. 13:41:58(UTC)
| Причина: Не указана
|