Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline DimKaKiber  
#1 Оставлено : 13 июля 2012 г. 13:33:57(UTC)
DimKaKiber

Статус: Участник

Группы: Участники
Зарегистрирован: 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 в конце концов), но так и не могу отыскать ошибку или неправльные действия во время выполнения операций.
Очень надеюсь, что Ваши ответы смогут направить меня в нужном направлении..............
Offline Kirill Sobolev  
#2 Оставлено : 13 июля 2012 г. 14:54:52(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,733
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Попробуйте зашифровать а потом расшифровать в свой адрес, т.е. когда отправитель и получатель совпадают.
Техническую поддержку оказываем тут
Наша база знаний
Offline DimKaKiber  
#3 Оставлено : 13 июля 2012 г. 15:30:56(UTC)
DimKaKiber

Статус: Участник

Группы: Участники
Зарегистрирован: 12.07.2012(UTC)
Сообщений: 16
Откуда: Томск

Если правильно понял, то Вы предлагаете заменить имена контейнеров - Sender и Reserver на одно и тоже имя контейнера, например, просто Sender и там и там??
К сожалению уже делал так и изменений не произошло((
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.