У меня есть программа Delphi 10.4 с клиентским набором данных, загружающая файлы XML, которые пользователи выбирают с помощью диалогового окна OpenFile. Он отлично работает, и в зависимости от содержимого XML структура fielddef устанавливается автоматически.
Теперь я хочу иметь возможность читать расшифрованные файлы и с помощью ClientDataSet.SaveToFile сохранять зашифрованные файлы.
В настоящее время я использую Lockbox 3.7 для расшифровки выбранного файла, создавая временный файл, который затем читается loadfromfile. Аналогичным образом Savetofile записывает данные обратно во временный файл, который затем шифруется и получает выбранное имя. Это работает очень хорошо, но оставляет временный файл на диске. И даже если я удалю временный файл в коде, восстановить его относительно легко, если знать как. Таким образом, безопасность с таким шифрованием в конце концов не так высока.
Я хотел бы иметь возможность выполнять расшифровку непосредственно в LoadFromFile (и аналогичное шифрование в SaveToFile) в качестве функции fileEn (или De) Crypt, как это было предложено субъектом, без использования временных файлов, но не смог найти какие-либо полезные функции.
Кто-нибудь знает о такой функции? Если это так, пожалуйста, укажите мне в правильном направлении. Последние пару дней я использовал Google для поиска чего-то полезного, но он оставил меня еще более запутанным и потерянным, чем раньше.
Альтернативное решение, при котором временные файлы, созданные LockBox EnCryptFile (и DeCryptFile), полностью уничтожаются до такой степени, что восстановление невозможно, подойдет как временное решение, поэтому указатели на способы полного уничтожения файла также будут приветствоваться. .
Заранее спасибо за любую помощь, которую я могу получить.





Используйте ClientDataSet.LoadFromStream вместо LoadFromFile. Я уверен, что у LockBox есть функция расшифровки в TStream. Используйте TMemoryStream, чтобы не сохранять расшифрованные данные на диск.
Аналогичным образом запишите набор данных клиента в поток (SaveToStream), используйте TMemoryStream, и он останется в памяти. Затем зашифруйте его и сохраните результат на диск.
Что касается альтернативного решения: я нашел пример DeleteAndWipe с предложениями несколько раз перезаписать временный файл разными значениями перед его удалением. Я тоже так попробую.
@lscshj Если в LockBox есть EncryptStream, сохраните ClientDataSet в TMemoryStream и сохраните зашифрованный strream в файл с помощью MemoryStream.SaveToFile. И наоборот, загрузите файл с помощью TMemoryStream с его LoadFromFile, расшифруйте поток с помощью Lockbox и загрузите ClientDataSet с этим расшифрованным потоком. Забудьте об DeleteAndWipe, потому что, если вы сломаете программу (возможно, намеренно), декодированные данные останутся там.
Пьетт: Спасибо за ваш вклад. Я принял ваш ответ.
И немного повозившись, я придумал следующее решение. Пожалуйста, не комментируйте отсутствующую проверку ошибок (try-Except) или уборку (try-Final), так как это только тест. В окончательном коде все проверки будут выполнены, и пользователи будут уведомлены в случае возникновения ошибок. Я также изменю его на функцию, возвращающую истину или ложь, в зависимости от успеха или нет.
И еще несколько слов для уточнения: На форме у меня есть TCryptographicLibrary и TCodec из Lockbox 3.7. Codec ChainMode и Cipher выбираются пользователем перед выбором файла для загрузки, и пользователь также предоставляет пароль, используемый в качестве ключа. Файл выбирается с помощью OpenDialog. Также на форме есть TClientDataSet, TDataSource, TDBGrid и TDBNavigator.
Я какое-то время возился с сообщением «Отсутствует поставщик данных или пакет данных» во время ClientDataSet.LoadFromStream, и причиной оказалось отсутствие поиска в потоке. Отсюда строка: XMLSt.Seek(0, soBeginning); непосредственно перед загрузкой потока.
Этот код работает, предоставляя мне заполненную DBGrid с полями, определениями и данными в соответствии с выбранным файлом XML.
Procedure TForm1.LoadFile(FileName : String; PassWord : string);
var XMLSt : TMemoryStream;
DecSt : TMemoryStream;
begin
DecSt := TMemoryStream.Create;
DecSt.LoadFromFile(FileName);
XMLSt := TMemoryStream.Create;
Codec1.Password := PassWord;
Codec1.DeCryptStream(XMLSt,DecSt);
XMLSt.Seek(0, soBeginning);
ClientDataSet1.LoadFromStream(XMLSt);
XmlSt.Free;
DecSt.Free;
ClientDataSet1.Active := true;
end;
А если выполнить операцию в обратном порядке, используя вместо этого ClientDataSet.SaveToStream, Codec1.EnCryptStream и TMemoryStream.SaveToStream, содержимое ClientDataSet будет сохранено в виде зашифрованного XML-файла.
Черт! Этот тест представляет собой форму, позволяющую пользователю выбрать расшифрованный файл XML, отредактировать содержимое и (после создания соответствующего файла сохранения) снова сохранить содержимое в виде зашифрованного файла XML. Относительно легко удалить визуальные компоненты и создать их во время выполнения, что позволяет сделать это общей функцией, транспортирующей зашифрованные данные из XML-файла в ClientDataSet и обратно.
Еще раз, спасибо за ваш вклад!
Спасибо за комментарий. Насколько я вижу, в Lockbox есть EnCryptStream и DeCryptStream, но они такие же процедуры, как и DecryptFile. Я попробую попробовать с MemoryStream и посмотрю, куда это меня приведет. Еще раз спасибо.