Статус: Активный участник
Группы: Участники
Зарегистрирован: 13.06.2013(UTC) Сообщений: 83 Откуда: Москва Сказал(а) «Спасибо»: 16 раз Поблагодарили: 1 раз в 1 постах
|
Поясню для чего все это нужно. Например, для встречного тестирования "зталонная" реализация (на КриптоПро) - "своя" реализация (с использованием openSSL, например). Вот код тогоже файла a.c (где мы получаем ключ из КриптоПро в открытом виде и потом устанавливаем его же у себя, в своей реализации): Цитата: #include <stdio.h> #include <windows.h> #include <wincrypt.h> #include "WinCryptEx.h"
#define CONTAINER_256 "\\\\.\\REGISTRY\\t_cc_encr_256" #define CONTAINER_512 "\\\\.\\REGISTRY\\t_cc_encr_512"
unsigned char PIN_TO_CONT[]={'1','1','1','1','1','1','1','1','\0'};
HCRYPTPROV hProv = 0; HCRYPTKEY hKey = 0;
//получить ключ в открытом виде //в случае успешного выполнения возвращает 1, в случае ошибки - 0 int GetKey(HCRYPTPROV * phProv, HCRYPTKEY * phKey, BYTE * pbOut) {
DWORD dwTmp; BYTE pbKeyBlobSimple[1024]; DWORD dwBlobLenSimple=1024; BYTE dt[G28147_KEYLEN]; BYTE im[EXPORT_IMIT_SIZE]; BYTE im2[EXPORT_IMIT_SIZE]; BYTE iv[SEANCE_VECTOR_LEN]; HCRYPTKEY hTempKey = 0; HCRYPTHASH hTempHash = 0;
//генерим временный ключ на котором будем делать экспорт нашего ключа if(!CryptGenKey(*phProv, CALG_G28147, CRYPT_EXPORTABLE, &hTempKey)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } //экспортируем (зашифровываем) ключ на временном ключе dwTmp = CALG_SIMPLE_EXPORT; if(!CryptSetKeyParam(hTempKey, KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } dwTmp = CRYPT_MODE_ECB; if(!CryptSetKeyParam(hTempKey, KP_MODE, (BYTE*)&dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } dwTmp = ZERO_PADDING; if(!CryptSetKeyParam(hTempKey, KP_PADDING, (BYTE*)&dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } memset(iv,0,SEANCE_VECTOR_LEN); if(!CryptSetKeyParam(hTempKey, KP_IV, iv, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } if(!CryptExportKey(*phKey, hTempKey, SIMPLEBLOB, 0, pbKeyBlobSimple, &dwBlobLenSimple)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } 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); //и сразу расшифровываем экспортированный ключ на том же временном ключе dwTmp = CALG_G28147; if(!CryptSetKeyParam(hTempKey , KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } dwTmp = G28147_KEYLEN; if(!CryptDecrypt(hTempKey, 0, TRUE, 0, dt, &dwTmp)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } //вычисляем имиту по расшифрованному ключу if(!CryptCreateHash(*phProv, CALG_G28147_IMIT, hTempKey, 0, &hTempHash)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } dwTmp = G28147_KEYLEN; if(!CryptHashData(hTempHash, dt, dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } dwTmp = EXPORT_IMIT_SIZE; if(!CryptGetHashParam(hTempHash, HP_HASHVAL, im2, &dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } if(memcmp(im,im2,EXPORT_IMIT_SIZE)!=0){ printf("\nLine:%d, Error:Wrong Imit\n",__LINE__);return 0; } if(hTempHash)CryptDestroyHash(hTempHash); if(hTempKey)CryptDestroyKey(hTempKey); memcpy(pbOut,dt,G28147_KEYLEN); return 1; }
int main(){ unsigned char K[32]; DWORD dwTmp; int i;
for(i=1;i>=0;--i){
// Получение дескриптора контекста криптографического провайдера if(CryptAcquireContext( &hProv, i?CONTAINER_256:CONTAINER_512, NULL, i?PROV_GOST_2012_256:PROV_GOST_2012_512, 0) ) { CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, PIN_TO_CONT, 0); if(!CryptAcquireContext( &hProv, i?CONTAINER_256:CONTAINER_512, NULL, i?PROV_GOST_2012_256:PROV_GOST_2012_512, CRYPT_DELETEKEYSET) ) { printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } } //создаем новый контейнер if(!CryptAcquireContext( &hProv, i?CONTAINER_256:CONTAINER_512, NULL, i?PROV_GOST_2012_256:PROV_GOST_2012_512, CRYPT_NEWKEYSET) ) { printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; }
//установка ПИНа на контейнер CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, PIN_TO_CONT, 0);
if(!CryptGenKey(hProv, i?CALG_GR3412_2015_M:CALG_GR3412_2015_K, CRYPT_EXPORTABLE, &hKey)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; }
if(!GetKey(&hProv, &hKey,K)){ printf("\nLine:%d, GetKey error\n",__LINE__);return 0; }
dwTmp = i?CALG_GR3412_2015_M:CALG_GR3412_2015_K; if(!CryptSetKeyParam(hKey, KP_ALGID, (BYTE*)&dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } dwTmp = ZERO_PADDING; if(!CryptSetKeyParam(hKey, KP_PADDING, (BYTE*)&dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; } dwTmp = CRYPT_SIMPLEMIX_MODE; if(!CryptSetKeyParam(hKey, KP_MIXMODE, (BYTE*)&dwTmp, 0)){ printf("\nLine:%d, Error:0x%x\n",__LINE__,GetLastError());return 0; }
// ключ (Магма/Кузнечик) получен в открытом виде // начинается встречное тестирование зашифрования/расшифрования "КриптоПро - openSSL/gost_engine" // ...
}
return 0;
}
Отредактировано пользователем 7 марта 2023 г. 12:55:00(UTC)
| Причина: <WinCryptEx.h> --> "WinCryptEx.h"
|