Вход | Регистрация
 
Информационные технологии :: Математика и алгоритмы

Шифрование потока в Lazarus

Шифрование потока в Lazarus
Я
   Провинциальный 1сник
 
31.01.20 - 14:54
Нужно шифровать поток(стрим) TMemoryStream, используя лазарусовкую библиотеку blowfish, вроде всё очевидно на первый взгляд. Но не работает загрузка зашифрованного потока в исходный поток. Ругается, что "seek not allowed on encryption streams". Судя по хелпу, метод LoadFromStream производит обращение к свойству Size исходного стрима, которое не определено для TBlowFishEncryptStream. Пробовал альтернативно - чтением из TBlowFishEncryptStream методом Read в буфер - ругается, что "reading not supported".

Тогда как иначе "перекачать" данные?

На выходе процедуры нужно, чтобы параметр Stream содержал своё исходное содержимое, но зашифрованное.

Подскажите, кто сталкивался?

Пример, нерабочий:
----

procedure EncryptStream(Stream:TMemoryStream);
var
   ES:TBlowFishEncryptStream;
begin
     ES:=TBlowFishEncryptStream.Create(Key,Stream);
     Stream.LoadFromStream(ES);
end;
 
 
   Nikoss
 
1 - 31.01.20 - 14:55
тыж Провинциальный 1сник, куда тебя понесло?))
   Midrash
 
2 - 31.01.20 - 14:57
(0) Нормальные герои всегда идут в обход!
   Midrash
 
3 - 31.01.20 - 14:58
(0) Уж сколько раз твердили миру, что надо использовать проверенные решения
   Провинциальный 1сник
 
4 - 31.01.20 - 14:59
(1) А что не так. Есть задачка, захотелось вспомнить молодость с дельфи.
(3) Какие?
Просьба отвечать по сути - кто в лазарусе работал с этой библиотекой..
   fisher
 
6 - 31.01.20 - 15:06
"TBlowFishEncryptStream example" пробовал в гугле набирать? Или оставил запасным вариантом?
   Провинциальный 1сник
 
7 - 31.01.20 - 15:28
(6) Да искал конечно. Но там везде тестовые примеры с шифрованием строки. А мне надо бинарный стрим.
   fisher
 
8 - 31.01.20 - 16:03
(7) Я вообще не очень понимаю, как ты собираешься "загружать" зашифрованный поток в исходный. Это же потоки. У них в общем случае "конец" заранее неизвестен. Работа с потоками выглядит как процесс, а не как операция. Ты пытаешься создать стрим, который является источником данных для себя самого. ИМХО, такая змея кусающая себя за хвост взлететь не сможет.
   H A D G E H O G s
 
9 - 31.01.20 - 16:20
(0) Поставь себе нормальный Дельфи и не парь мозг
   H A D G E H O G s
 
10 - 31.01.20 - 16:21
TBlowFishEncryptStream от Лазаруса писали ушлепки
   H A D G E H O G s
 
11 - 31.01.20 - 16:22
Свободное ПО - зло
   Провинциальный 1сник
 
12 - 31.01.20 - 16:28
(8) Да, я понял что не так было. Переписал. Шифрует, то есть какие-то данные я получаю (проверял через сохранение потока в файл). Но теперь другая проблема - шифровать то шифрует, но не расшифровывает то что зашифровал. Вернее, при расшифровке получаю мусор. Вроде всё делаю по примерам..
Вот новый код:


procedure EncryptStream(Stream:TMemoryStream);
var
   NewMS:TMemoryStream;
   ES:TBlowFishEncryptStream;
begin
  try
     NewMS:=TMemoryStream.Create;
     ES:=TBlowFishEncryptStream.Create(Key,NewMS);
     ES.CopyFrom(Stream,Stream.Size);
     ES.Flush;
     Stream.LoadFromStream(NewMS);
  finally
    ES.Free;
    NewMS.Free;
  end;
end;

procedure DecryptStream(Stream:TMemoryStream);
var
   DS:TBlowFishDecryptStream;
   NewMS:TMemoryStream;
begin
  try
     NewMS:=TMemoryStream.Create;
     DS:=TBlowFishDecryptStream.Create(Key,Stream);
     NewMS.CopyFrom(DS,Stream.Size);
     Stream.LoadFromStream(NewMS);
  finally
    DS.Free;
    NewMS.Free;
  end;
end;
   Garykom
 
13 - 31.01.20 - 16:35
(9) (10) (11) Может просто готовить Лазарус не умеешь? Он вполне неплох для своих целей и не стоит таких бешеных денег как лицензионная Delphi.
   Garykom
 
14 - 31.01.20 - 16:37
(12) Гм тебе бы основы подучить работы с потоками ты косячишь пипец
   Garykom
 
15 - 31.01.20 - 16:38
(14)+ Для начала какого хера ты берешь один входящий в процедуру поток и засовывашь снова в него назад? А куда дел исходный если там еще данные после пойдут и куда засунешь?
   Провинциальный 1сник
 
16 - 31.01.20 - 16:40
(15) Это TMemoryStream, с ним так можно работать. Просто способ обращения к буферу в памяти с данными.
   Garykom
 
17 - 31.01.20 - 16:42
(16) SetSize где?
   Провинциальный 1сник
 
18 - 31.01.20 - 16:45
(17) А оно нафига? Если я изначально загружаю в стрим данные из файла, а потом - копирую из другого стрима?
   fisher
 
19 - 31.01.20 - 16:58
(12) В шифровании вроде норм. А в дешифровке фигня какая-то.
   Провинциальный 1сник
 
20 - 31.01.20 - 16:59
(19) По образцу делал, может что и не так(
   fisher
 
21 - 31.01.20 - 17:00
Попробуй так
procedure DecryptStream(Stream:TMemoryStream);
var
   DS:TBlowFishDecryptStream;
   NewMS:TMemoryStream;
begin
  try
     NewMS:=TMemoryStream.Create;
     DS:=TBlowFishDecryptStream.Create(Key,NewMS);
     DS.CopyFrom(Stream,Stream.Size);
     Stream.LoadFromStream(DS);
  finally
    DS.Free;
    NewMS.Free;
  end;
end;
   Провинциальный 1сник
 
22 - 31.01.20 - 19:23
(21) "Stream read error" на строчке DS.CopyFrom(Stream,Stream.Size);
   v77
 
23 - 01.02.20 - 11:47
Вот так работает

function EncriptStream(password : string; AnyStream : TStream) : TMemoryStream;
var
  en : TBlowFishEncryptStream;
begin
  result := TMemoryStream.Create;
  en := TBlowFishEncryptStream.Create(password,result);
  try
    AnyStream.Position := 0;
    en.CopyFrom(AnyStream, AnyStream.Size);
  finally
    en.Free;
  end;
end;

function DecriptStream(password : string; EncriptedStream : TStream) : TStringStream;
var
  de : TBlowFishDeCryptStream;
begin
  de := TBlowFishDeCryptStream.Create(password, EncriptedStream);
  result := TStringStream.Create('');
  try
    EncriptedStream.Position := 0;
    result.CopyFrom(de, EncriptedStream.Size);
  finally
    de.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s, d : TStringStream;
  M : TMemoryStream;
begin
  s := TStringStream.Create('Данные для расшифровки');
  M := EncriptStream('secret123',s);
  d := DecriptStream('secret123',M);

  ShowMessage(d.DataString);

  m.Free;
  s.Free;
  d.Free;
end; 

   Провинциальный 1сник
 
24 - 01.02.20 - 16:45
Мне не надо строки шифровать и расшифровывать. Задача требует работы с произвольными бинарными данными в памяти... Со строками примеров в интернете куча, это не то, что требуется.
   Garykom
 
25 - 01.02.20 - 17:11
(24) Ты блин заменить тип не можешь что ли?
   v77
 
26 - 01.02.20 - 17:40
(24) замени в DecriptStream TStringStream на TMemoryStream
хотя без разницы. И там и там байтики.
   v77
 
27 - 01.02.20 - 17:53
[1C]
function DecriptStream(password : string; EncriptedStream : TStream) : TMemoryStream;
var
  de : TBlowFishDeCryptStream;
begin
  de := TBlowFishDeCryptStream.Create(password, EncriptedStream);
  result := TMemoryStream.Create('');
  try
    EncriptedStream.Position := 0;
    result.CopyFrom(de, EncriptedStream.Size);
  finally
    de.Free;
  end;
end;
[/1C]
   v77
 
28 - 01.02.20 - 18:25
На вот файлы шифрует
procedure EncriptStream(password : string; AnyStream, OutStream : TStream);
var
  en : TBlowFishEncryptStream;
begin
  en := TBlowFishEncryptStream.Create(password,OutStream);
  try
    AnyStream.Position := 0;
    en.CopyFrom(AnyStream, AnyStream.Size);
  finally
    en.Free;
  end;
end;

procedure DecriptStream(password : string; EncriptedStream, OutStream : TStream);
var
  de : TBlowFishDeCryptStream;
begin
  de := TBlowFishDeCryptStream.Create(password, EncriptedStream);
  try
    EncriptedStream.Position := 0;
    OutStream.CopyFrom(de, EncriptedStream.Size);
  finally
    de.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Data, EncriptedData : TStream;
begin
  Data := TFileStream.Create('test.txt', fmOpenRead);
  EncriptedData := TFileStream.Create('encripted_test.txt', fmCreate);
  EncriptStream('pass123', Data, EncriptedData);
  Data.Free;
  EncriptedData.Free;

  Data := TFileStream.Create('test_decripted.txt', fmCreate);
  EncriptedData := TFileStream.Create('encripted_test.txt', fmOpenRead);
  DecriptStream('pass123', EncriptedData, Data);
  Data.Free;
  EncriptedData.Free;
end; 

   Провинциальный 1сник
 
29 - 02.02.20 - 09:58
(28) Спасибо за помощь! Я понял, что у меня было не так. Перед CopyFrom не было установки позиции чтения стрима в 0. В результате обращение было к чему-то левому из памяти за концом буфера мемористрима. Поправил, теперь работает правильно.

И ещё вопросик - расшифрованные данные дополняются нулевыми байтами до величины, кратной 8 байтам. Это как-то лечится штатно? Или только отдельно где-то хранить исходную длину данных, чтобы потом подрезать?
   v77
 
30 - 02.02.20 - 11:33
(29) "расшифрованные данные дополняются нулевыми байтами"
у меня ничего не дополняется
 
 Рекламное место пустует
   Провинциальный 1сник
 
31 - 02.02.20 - 11:36
(30) А вы чем смотрите, блокнотом? Я взял ваш код целиком - дополняются. Смотрите фаром, например. Или по размеру файла.
   v77
 
32 - 02.02.20 - 11:39
(31) если дополняет, то записывай в начало размер и шифруй
   Garykom
 
33 - 02.02.20 - 12:04
(31) Длина исходных и зашифрованных данных отличается.
И если взять поток длиной с исходные то записав туда зашифрованные (и наоборот) получатся разные приколы.
   Провинциальный 1сник
 
34 - 02.02.20 - 12:16
(32) Да, сделал через сохранение реальной длины в зашифрованном потоке. Спасибо ещё раз!


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.