| ||||
| ||||
// * * Расшифровка 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, @hk) then <Error...> //Читаю открытый ключ AssignFile(outfile, OpenDlg.FileName); reset(outfile, 1); keyLen := FileSize(outfile); GetMem(tmp, keyLen); BlockRead(outfile, tmp^, keyLen); CloseFile(outfile); //Импортирую его if not CryptImportKey(hProv, tmp, keyLen, hk, 0, @KeyExchKey) then <Error...> FreeMem(tmp, keyLen); //Читаю сеансовый ключ 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...> Получаю ошибку - NTE_BAD_DATA. Подскажите в чем проблема. Буду признателен за пример кода. | ||||
Ответы: | ||||
| ||||
Так не скажешь... Нужны подробности Одинаковые ли алгоритмы ключей AT_KEYEXCHANGE отправителя и получателя? Т.е. в Вашем случае должен быть ГОСТ 2001-го года. Или хотя бы сообщите размеры блобов открытого ключа и сеансового ключа. Если да - приведите код экспорта ключей (открытого, сеансового), а также - одинаковые ли CSP при экспорте ключей и импорте их? | ||||
| ||||
Я новичок, поэтому мог что-то напутать. Уже долго мучаюсь, помогите справиться с проблемой. Последовательность действий: Делаю так: Создаю последовательно два тестовых сертификата (http://www.cryptopro.ru/certsrv/) и помещаю их на две дискеты (дискету "а" и дискету "b"). Помещаю дискету "а" и экспортирую ключ обмена ключами в файл "pubkey_a". Помещаю дискету "b" и с использование "pubkey_a" шифрую файл. Зашифрованный файл - "test_enc.txt". Помещаю дискету "а" и пытаюсь расшифровать "test_enc.txt". Получаю ошибку NTE_BAD_DATA. Код и размеры блоков (Delphi): I) Экспорт ключа обмена ключами (дискета "а") 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); <<-- bufLen == 100 if not CryptExportKey(key, 0, PUBLICKEYBLOB, 0, pbuf, @bufLen)) then <Error...> if not CryptDestroyKey(key) then <Error...> rewrite(f, 1); BlockWrite(f, pbuf^, bufLen); CloseFile(f); if not CryptReleaseContext(hProv, 0) then then <Error...> Создался файл "pubkey_a". Размер 100 Б II) Шифрование файла (дискета "b") if not CryptAcquireContext(@hProv, cont, 'Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider', 75, 0) <Error...> //Читаю файл "pubkey_a" reset(outfile, 1); keyLen := FileSize(outfile); <<-- keyLen == 100 GetMem(tmp, keyLen); BlockRead(outfile, tmp^, keyLen); CloseFile(outfile); if not CryptGetUserKey(hProv,AT_KEYEXCHANGE,@hk) then <Error...> if not CryptImportKey(hProv, tmp, keyLen, hk, CRYPT_EXPORTABLE, @KeyExchKey) then <Error...> FreeMem(tmp, keyLen); //Генерируем ключ 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...> //Записываем в файл (1) BlockWrite(outfile, keyLen, 4); <<-- keyLen == 71 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...> //Записываем в файл (2) BlockWrite(outfile, keyLen, 4); <<-- keyLen == 8 BlockWrite(outfile, buf, keyLen); //Записываем в файл (3) 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...> Создался файл "test_enc.txt". III) Расшифровка файла (дискета "a") //Читаю файл "pubkey_a" reset(outfile, 1); keyLen := FileSize(outfile); GetMem(tmp, keyLen); <<-- keyLen == 100 BlockRead(outfile, tmp^, keyLen); CloseFile(outfile); if not CryptGetUserKey(hProv,AT_KEYEXCHANGE,@hk) then <Error...> if not CryptImportKey(hProv, tmp, keyLen, hk, CRYPT_EXPORTABLE, @KeyExchKey) then <Error...> FreeMem(tmp, keyLen); //Читаю "test_enc.txt" (1 - сеансовый ключ) reset(infile, 1); BlockRead(infile, keyLen, 4); <<-- keyLen == 71 GetMem(tmp, keyLen); BlockRead(infile, tmp^, keyLen); if not CryptImportKey(hProv, tmp, keyLen, KeyExchKey, 0, @SessionKey) then <Error...> Получаю ошибку - NTE_BAD_DATA. | ||||
| ||||
Почти всё правильно. Только не хватает: на этапе II - экспорта в PUBLICKEYBLOB ключа hk из контейнера дискеты б (в файл pubkey_b) на этапе III - вместо чтения из pubkey_a следует читать из pubkey_b | ||||
| ||||
Не идет, снова ошибка. Блок (II). Сразу после строки if not CryptGetUserKey(hProv,AT_KEYEXCHANGE,@hk) then <Error...> пишу: if not CryptExportKey(hk, 0, PUBLICKEYBLOB, 0, nil, @bufLen) then <Error...> GetMem(pbuf, bufLen); <<-- bufLen == 100 if CryptExportKey(hk, 0, PUBLICKEYBLOB, 0, pbuf, @bufLen) then <Error...> Ошибка! | ||||
| ||||
Последний вопрос снимается. Сам ошибся. | ||||