Имя: Пароль:
IT
 
Шифрование потока в Lazarus
0 Провинциальный 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;
1 Nikoss
 
31.01.20
14:55
тыж Провинциальный 1сник, куда тебя понесло?))
2 Midrash
 
31.01.20
14:57
(0) Нормальные герои всегда идут в обход!
3 Midrash
 
31.01.20
14:58
(0) Уж сколько раз твердили миру, что надо использовать проверенные решения
4 Провинциальный 1сник
 
31.01.20
14:59
(1) А что не так. Есть задачка, захотелось вспомнить молодость с дельфи.
(3) Какие?
Просьба отвечать по сути - кто в лазарусе работал с этой библиотекой..
6 fisher
 
31.01.20
15:06
"TBlowFishEncryptStream example" пробовал в гугле набирать? Или оставил запасным вариантом?
7 Провинциальный 1сник
 
31.01.20
15:28
(6) Да искал конечно. Но там везде тестовые примеры с шифрованием строки. А мне надо бинарный стрим.
8 fisher
 
31.01.20
16:03
(7) Я вообще не очень понимаю, как ты собираешься "загружать" зашифрованный поток в исходный. Это же потоки. У них в общем случае "конец" заранее неизвестен. Работа с потоками выглядит как процесс, а не как операция. Ты пытаешься создать стрим, который является источником данных для себя самого. ИМХО, такая змея кусающая себя за хвост взлететь не сможет.
9 H A D G E H O G s
 
31.01.20
16:20
(0) Поставь себе нормальный Дельфи и не парь мозг
10 H A D G E H O G s
 
31.01.20
16:21
TBlowFishEncryptStream от Лазаруса писали ушлепки
11 H A D G E H O G s
 
31.01.20
16:22
Свободное ПО - зло
12 Провинциальный 1сник
 
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;
13 Garykom
 
гуру
31.01.20
16:35
(9) (10) (11) Может просто готовить Лазарус не умеешь? Он вполне неплох для своих целей и не стоит таких бешеных денег как лицензионная Delphi.
14 Garykom
 
гуру
31.01.20
16:37
(12) Гм тебе бы основы подучить работы с потоками ты косячишь пипец
15 Garykom
 
гуру
31.01.20
16:38
(14)+ Для начала какого хера ты берешь один входящий в процедуру поток и засовывашь снова в него назад? А куда дел исходный если там еще данные после пойдут и куда засунешь?
16 Провинциальный 1сник
 
31.01.20
16:40
(15) Это TMemoryStream, с ним так можно работать. Просто способ обращения к буферу в памяти с данными.
17 Garykom
 
гуру
31.01.20
16:42
(16) SetSize где?
18 Провинциальный 1сник
 
31.01.20
16:45
(17) А оно нафига? Если я изначально загружаю в стрим данные из файла, а потом - копирую из другого стрима?
19 fisher
 
31.01.20
16:58
(12) В шифровании вроде норм. А в дешифровке фигня какая-то.
20 Провинциальный 1сник
 
31.01.20
16:59
(19) По образцу делал, может что и не так(
21 fisher
 
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;
22 Провинциальный 1сник
 
31.01.20
19:23
(21) "Stream read error" на строчке DS.CopyFrom(Stream,Stream.Size);
23 v77
 
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;
24 Провинциальный 1сник
 
01.02.20
16:45
Мне не надо строки шифровать и расшифровывать. Задача требует работы с произвольными бинарными данными в памяти... Со строками примеров в интернете куча, это не то, что требуется.
25 Garykom
 
гуру
01.02.20
17:11
(24) Ты блин заменить тип не можешь что ли?
26 v77
 
01.02.20
17:40
(24) замени в DecriptStream TStringStream на TMemoryStream
хотя без разницы. И там и там байтики.
27 v77
 
01.02.20
17:53

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

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