ClientDatSet.LoadFromFile(DeCryptFile(XMLFile))?

У меня есть программа Delphi 10.4 с клиентским набором данных, загружающая файлы XML, которые пользователи выбирают с помощью диалогового окна OpenFile. Он отлично работает, и в зависимости от содержимого XML структура fielddef устанавливается автоматически.

Теперь я хочу иметь возможность читать расшифрованные файлы и с помощью ClientDataSet.SaveToFile сохранять зашифрованные файлы.

В настоящее время я использую Lockbox 3.7 для расшифровки выбранного файла, создавая временный файл, который затем читается loadfromfile. Аналогичным образом Savetofile записывает данные обратно во временный файл, который затем шифруется и получает выбранное имя. Это работает очень хорошо, но оставляет временный файл на диске. И даже если я удалю временный файл в коде, восстановить его относительно легко, если знать как. Таким образом, безопасность с таким шифрованием в конце концов не так высока.

Я хотел бы иметь возможность выполнять расшифровку непосредственно в LoadFromFile (и аналогичное шифрование в SaveToFile) в качестве функции fileEn (или De) Crypt, как это было предложено субъектом, без использования временных файлов, но не смог найти какие-либо полезные функции.

Кто-нибудь знает о такой функции? Если это так, пожалуйста, укажите мне в правильном направлении. Последние пару дней я использовал Google для поиска чего-то полезного, но он оставил меня еще более запутанным и потерянным, чем раньше.

Альтернативное решение, при котором временные файлы, созданные LockBox EnCryptFile (и DeCryptFile), полностью уничтожаются до такой степени, что восстановление невозможно, подойдет как временное решение, поэтому указатели на способы полного уничтожения файла также будут приветствоваться. .

Заранее спасибо за любую помощь, которую я могу получить.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
361
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используйте ClientDataSet.LoadFromStream вместо LoadFromFile. Я уверен, что у LockBox есть функция расшифровки в TStream. Используйте TMemoryStream, чтобы не сохранять расшифрованные данные на диск.

Аналогичным образом запишите набор данных клиента в поток (SaveToStream), используйте TMemoryStream, и он останется в памяти. Затем зашифруйте его и сохраните результат на диск.

Спасибо за комментарий. Насколько я вижу, в Lockbox есть EnCryptStream и DeCryptStream, но они такие же процедуры, как и DecryptFile. Я попробую попробовать с MemoryStream и посмотрю, куда это меня приведет. Еще раз спасибо.

lscshj 10.12.2020 16:56

Что касается альтернативного решения: я нашел пример DeleteAndWipe с предложениями несколько раз перезаписать временный файл разными значениями перед его удалением. Я тоже так попробую.

lscshj 10.12.2020 16:58

@lscshj Если в LockBox есть EncryptStream, сохраните ClientDataSet в TMemoryStream и сохраните зашифрованный strream в файл с помощью MemoryStream.SaveToFile. И наоборот, загрузите файл с помощью TMemoryStream с его LoadFromFile, расшифруйте поток с помощью Lockbox и загрузите ClientDataSet с этим расшифрованным потоком. Забудьте об DeleteAndWipe, потому что, если вы сломаете программу (возможно, намеренно), декодированные данные останутся там.

fpiette 10.12.2020 17:18

Пьетт: Спасибо за ваш вклад. Я принял ваш ответ.

И немного повозившись, я придумал следующее решение. Пожалуйста, не комментируйте отсутствующую проверку ошибок (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 и обратно.

Еще раз, спасибо за ваш вклад!

Другие вопросы по теме