| ||||
| ||||
Здравствуйте. При попытке импорта сеансового ключа получаю ошибку NTE_BAD_TYPE. Ниже привожу код на Delphi как все пытался сделать. Этот код работает с криптопровайдером Microsoft. Подскажите, пожалуйста, где я совершил ошибку. // * * Генерация if not CryptAcquireContext(@hProv, cont, 'Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider', 75, CRYPT_NEWKEYSET) then <Error...> keyLen := 512; flag := keyLen shl 16; if not CryptGenKey(hProv, AT_KEYEXCHANGE, flag, @KeyExchKey) then <Error...> flag := 4; if not CryptGetKeyParam(KeyExchKey, KP_KEYLEN, @keyLen, @flag, 0) then <Error...> {длинна - 512} if not CryptReleaseContext(hProv, 0) then <Error...> // * * Экспорт ключа if not CryptAcquireContext(@hProv, nil, 'Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider', 75, 0) then <Error...> if not CryptGetUserKey(hProv, AT_KEYEXCHANGE, @key) then <Error...> if not CryptExportKey(key, 0, PUBLICKEYBLOB, 0, nil, @bufLen) then <Error...> GetMem(pbuf, bufLen); if not CryptExportKey(key, 0, PUBLICKEYBLOB, 0, pbuf, @bufLen) then <Error...> if not CryptDestroyKey(key) then then <Error...> AssignFile(f, SaveDialog1.FileName); rewrite(f, 1); BlockWrite(f, pbuf^, bufLen); CloseFile(f); if not CryptReleaseContext(hProv, 0) then <Error...> // * * Шифрование if not CryptAcquireContext(@hProv, cont, 'Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider', 75, 0) then <Error...> //читаем файл с открытым ключом обмена ключами получателя AssignFile(outfile, OpenDlg.FileName); reset(outfile, 1); keyLen := FileSize(outfile); GetMem(tmp, keyLen); BlockRead(outfile, tmp^, keyLen); CloseFile(outfile); // Получение дескриптора закрытого ключа отправителя. {Не знаю зачем надо, но без нее CryptExportKey выдаст ошибку} if not CryptGetUserKey(hProv,AT_KEYEXCHANGE,@hk) then <Error...> // Импорт ключа, опять же надо hk или ставить 0 if not CryptImportKey(hProv, tmp, keyLen, hk, CRYPT_EXPORTABLE, @KeyExchKey) then <Error...> FreeMem(tmp, keyLen); rewrite(outfile, 1); if not CryptGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, @SessionKey) then <Error...> keyLen := 512; GetMem(tmp, keyLen); if not CryptExportKey(SessionKey, KeyExchKey, SIMPLEBLOB, 0, tmp, @keyLen) then <Error...> BlockWrite(outfile, keyLen, 4); BlockWrite(outfile, tmp^, keyLen); if not CryptDestroyKey(KeyExchKey) then <Error...> //создание IV keyLen := 512; if not CryptGetKeyParam(SessionKey, KP_IV, @buf, @keyLen, 0) then <Error...> if not CryptGenRandom(hProv, keyLen, @buf) then <Error...> if not CryptSetKeyParam(SessionKey, KP_IV, @buf, 0) then <Error...> BlockWrite(outfile, keyLen, 4); BlockWrite(outfile, buf, keyLen); reset(infile, 1); while not eof(infile) do begin BlockRead(infile, buf, 496, keyLen); if not CryptEncrypt(SessionKey, 0, eof(infile), 0, @buf, @keyLen, 512) then <Error...> BlockWrite(outfile, buf, keyLen); end; CloseFile(infile); CloseFile(outfile); if not CryptDestroyKey(SessionKey) then <Error...> if not CryptReleaseContext(hProv, 0) then <Error...> // * * Расшифровка if not CryptAcquireContext(@hProv, cont, 'Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider', 75, 0) then <Error...> if not CryptGetUserKey(hProv, AT_KEYEXCHANGE, @KeyExchKey) then <Error...> // Чтение зашифрованного файла reset(infile, 1); BlockRead(infile, keyLen, 4); GetMem(tmp, keyLen); BlockRead(infile, tmp^, keyLen); // Импорта сеансового ключа if not CryptImportKey(hProv, tmp, keyLen, KeyExchKey, 0, @SessionKey) then <Error...> Error -- NTE_BAD_TYPE | ||||
Ответы: | ||||
| ||||
Экспорт и импорт сессионного ключа возможен только на ключе парной связи (Диффи-Хеллмана). Ключ Д-Х получается импортом блоба PUBLICKEYBLOB на ключе AT_KEYEXCHANGE. При шифровании Вы сделали правильно. При расшифровании нужно сделать симметрично: 1) создание ключа Д-Х: чтение блоба PUBLICKEYBLOB из файла и импорт его на ключе AT_KEYEXCHANGE 2) чтение блоба сессионного ключа из файла и иморт его на ключе, созданном в предыдущем пункте | ||||