Статус: Участник
Группы: Участники
Зарегистрирован: 12.07.2012(UTC) Сообщений: 16 Откуда: Томск
|
Имеется Лицензия КриптоПро CSP 3.6. Передо мной была поставленна задача шифрования данных посредством этого криптопровайдера. Среда разработки - Delphi. Удалось создать ключевые контейнеры (без сертификата) и зашифровать файл. При расшифровке размер файла равняется размеру шмфруемого (в байтах). но получаются краказябры: Цитата:–ю^s|^ вэz РЖч'SNєIЁKпРШПчЬ]Yd(РЌ° КtБѕ¦.ј?¤QF Грешил на кодировку. но ри её изменении ничего не получается. Код мой шифрации: Код:ContName:='Sender';
cont:=StrAlloc(Length(ContName)+1);
StrPCopy(cont, ContName);
if not CryptAcquireContext(hProv, cont, nil, PROV_GOST_2001_DH, 0)
then
begin
//коды ошибок
end;
if err = 'NTE_BAD_KEYSET' then //Нету контейнера ==>> создаю его
MessageDlg('Не найден контейнер с именем: ' + ContName, mtInformation, [mbOK], 0);
end
else MessageDlg('Контейнер с именем ' + ContName + ' открыт', mtInformation, [mbOK], 0);
//Теперь приступаю к шифрации сообщения_
CryptMessagA:=TMemoryStream.Create;
CryptMessagA.LoadFromFile(ExtractFilePath(application.ExeName) +'ОРИГИНАЛ.txt');
CryptMessagA.Position:=0;
AssignFile(outfile,ExtractFilePath(application.ExeName) +'KeyChange.txt');//Открываем ключ_
reset(outfile, 1);
keyLen := FileSize(outfile);
GetMem(tmp, keyLen);
BlockRead(outfile, tmp^, keyLen);
CloseFile(outfile);
if not CryptImportKey(hProv, tmp, keyLen, 0, 0, KeyExchKey) then
begin
exit;
end;
FreeMem(tmp, keyLen);
stream:= true;
Crypter:= TMemoryStream.Create;
if not CryptGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, SessionKey) then
begin
exit;
end;
keyLen := 128;
GetMem(tmp, keyLen);
if not CryptExportKey(KeyExchKey,0 , PUBLICKEYBLOB, 0, tmp, keyLen) then
begin
exit;
end;
Crypter.Write(keyLen, 4);
Crypter.Write(tmp^, keyLen);
if not CryptDestroyKey(KeyExchKey) then
begin
exit;
end;
keyLen := 512;
if not CryptGetKeyParam(SessionKey, KP_ALGID, @buf, keyLen, 0) then
begin
exit;
end;
Crypter.Write(keyLen, 4);
Crypter.Write(buf, keyLen);
while CryptMessagA.Position < CryptMessagA.Size do
begin
keyLen := CryptMessagA.Read(buf, 496);
if not CryptEncrypt(SessionKey, 0, CryptMessagA.Position < CryptMessagA.Size, 0, @buf, keyLen, 512) then
begin
MessageDlg('Ошибка при шифровании: ' + ErrToStr(GetLastError),
mtError, [mbOK], 0);
exit;
end;
Crypter.Write(buf, keyLen);
end;
//Сохраняю зашифрованные данные в файл_
Crypter.SaveToFile(ExtractFilePath(application.ExeName) +'Зашифрованные данные.txt');
CryptDestroyKey(SessionKey);
CryptReleaseContext(hProv, 0);
Crypter.Free;
CryptMessagA.Free;
и соответственно расшифровки: Код:ContName:='Reserver';
cont:=StrAlloc(Length(ContName)+1);
StrPCopy(cont, ContName);
if not CryptAcquireContext(hProv, cont, nil, PROV_GOST_2001_DH, 0)
then
begin
//коды ошибок
end;
if err = 'NTE_BAD_KEYSET' then //Нету контейнера ==>> создаю его
MessageDlg('Не найден контейнер с именем: ' + ContName, mtInformation, [mbOK], 0);
end
else MessageDlg('Контейнер с именем ' + ContName + ' открыт', mtInformation, [mbOK], 0);
//Расшифровка сообщения_
Crypter:= TMemoryStream.Create;
Crypter.LoadFromFile(ExtractFilePath(application.ExeName) +'Зашифрованные данные.txt');
Crypter.Position:=0;
if not CryptGetUserKey(hProv, AT_KEYEXCHANGE, KeyExchKey) then
begin
exit;
end;
Crypter.Read(keyLen, 4);
GetMem(tmp, keyLen);
Crypter.Read(tmp^, keyLen);
if not CryptImportKey(hProv, tmp, keyLen, KeyExchKey, 0, SessionKey) then
begin
exit;
end;
FreeMem(tmp, keyLen);
if not CryptDestroyKey(KeyExchKey) then
begin
exit;
end;
Crypter.Read(keyLen, 4);
Crypter.Read(buf, keyLen);
if not CryptSetKeyParam(SessionKey, KP_ALGID, @buf, 0) then
begin
exit;
end;
keyLen := 4;
if not CryptGetKeyParam(SessionKey, KP_ALGID, @alg, keyLen, 0) then
begin
exit;
end;
Decrypter:=TMemoryStream.Create;
keylen:=Crypter.Read(buf, 512);
if not CryptDecrypt(SessionKey, 0, Crypter.Position < Crypter.Size, 0, @buf, keyLen) then
begin
exit;
end;
Decrypter.Write( buf, keyLen);
Decrypter.Position:=0;
//Сохраняю зашифрованные данные в файл_
Decrypter.SaveToFile(ExtractFilePath(application.ExeName) +'Расшифрованные данные.txt');
CryptDestroyKey(SessionKey);
CryptReleaseContext(hProv, 0);
Decrypter.Free;
Crypter.Free;
Уже перелопатил кучу статей. примеров (С+, Delphi, SDK в конце концов), но так и не могу отыскать ошибку или неправльные действия во время выполнения операций. Очень надеюсь, что Ваши ответы смогут направить меня в нужном направлении..............
|