Синхронизатор для обмена шифрованными файлами между программой CyberSafe и облачными ресурсами

Функция облачного шифрования CyberSafe позволяет осуществлять автоматическое копирование зашифрованных файлов на “облака”, такие как Google Диск (в этой статье рассмотрен именно этот облачный ресурс) и любые другие. При этом, если с облачной папкой работают одновременно несколько пользователей, реализована синхронизация зашифрованных файлов на компьютерах каждого из них. Общие принципы работы с функцией облачного шифрования были описаны здесь, в этой статье речь пойдет о работе самого синхронизатора.
Во время его разработки техническая проблема заключалась в том, что при синхронизации файлов из папки Google Диск на компьютере пользователя с Google веб-папкой в облаке, служебная информация о зашифрованных файлах, записанная в ADS не передается и теряется. То есть файлы на другие устройства после синхронизации попадают зашифрованными, но расшифровать их пользователь не может. Для решения этой проблемы был придуман вариант с созданием папки CyberSafe Cloud, которая является зеркальной для папки Google Диск. В эту папку пользователь копирует новые не зашифрованные файлы, которые автоматически шифруются драйвером прозрачного шифрования (Alfa Transparent File Encryptor Driver). Служебная информация для зашифрованного файла (хеш идентификатора ключа шифрования) размером 4096 байт, записывается в ADS и доступна драйверу для работы. В то же время в саму папку Google Диска зашифрованные файлы отправляются со служебной информацией, записанной в заголовок файла, без использования ADS, что позволяет сохранить ее при передаче на “облако”. Зеркальная папка создается CyberSafe автоматически при добавлении папки Google Диск в программу:

Администратор данной папки первым добавляет ее в CyberSafe и назначает ключи других пользователей, которые в виде цифрового конверта записываются в ADS папки. В папке Google Диск программа создает файл cybersafe.cloud.conf. Данный файл содержит информацию, аналогичную информации в ADS зашифрованной папки, а именно: симметричный ключ шифрования, защищенный открытыми ключами допущенных пользователей, ID этого ключа, список используемых сертификатов. Cybersafe.cloud.conf “путешествует” по интернету и распространяется на компьютеры пользователей, имеющих доступ к зашифрованной папке. Добавляя папку Google Диск в CyberSafe на своих компьютерах, пользователи уже не назначают ключи — информация переписывается в ADS данной папки на их компьютерах из cybersafe.cloud.conf. Теперь о том как работает синхронизатор. В программе есть два отдельных процесса CloudSync.exe и СloudSync2.exe, которые осуществляют синхронизацию между зеркальной папкой CyberSafe и папкой Google Диск. CloudSync.exe осуществляет копирование зашифрованных файлов со служебной информацией, помещенной в заголовок из зеркальной папки в папку Google Диск. Этот процесс добавлен в список “исключенных” для драйвера шифрования, что позволяет ему “видеть” файлы в зеркальной папке зашифрованными и со служебной информацией в заголовке (драйвер автоматически отображает информацию из ADS в заголовке файла для такого рода процессов). Процесс CloudSync.exe не имеет доступа отдельно к ADS файла. СloudSync2.exe — обычный процесс, который в зеркальной папке “видит” файлы расшифрованными, имеет доступ к ADS, может копировать файлы из папки Google Диск в зеркальную с последующим автоматическим шифрованием драйвером.

В процессе синхронизации файлов существует несколько вариантов развития событий: 1. В папку Google Диск копируется новый файл. Он может быть уже зашифрованным, будучи скопированым туда непосредственно из облака в результате действий, осуществленных на компьютерах других пользователей, либо не зашифрованным – сам пользователь копирует новый не зашифрованный файл в папку Google Диск на своем компьютере. Проверяется наличие служебного заголовка в начале фала. 1.1 Если заголовок есть, то считаем файл зашифрованным. Зашифрован файл или нет определяет процесс CloudSync.exe. Для этого анализируются первые 4096 байт файла на предмет наличия структуры заголовка ATE_HEADER с заполненными полями: ATE_HEADER = Record KeyIDLength, KeyXOR: DWORD; Data: Array[1..ATE_KEY_ID_SIZE div sizeof(DWORD)] Of DWORD; KeyIDLength2, KeyXOR2: DWORD; Data2: Array[1..ATE_KEY_ID_SIZE div sizeof(DWORD)] Of DWORD; Flags, Flags2: DWORD; cData: Array[0..3575] Of AnsiChar; End; Функция проверки зашифрован файл или нет: function isFileHasRightHeader(FileName: string): Boolean; var HEADER: ATE_HEADER; fs: TFileStream; begin Result := False; try fs := TFileStream.Create(FileName, fmOpenRead); try fs.Read(HEADER, SIZE_OF_ATE_HEADER); Result := (HEADER.KeyIDLength = ATE_KEY_ID_SIZE) and (HEADER.KeyIDLength2 = ATE_KEY_ID_SIZE); finally fs.Free; end; except on E: Exception do WriteToLog('!!! isFileHasRightHeader: ' + E.Message + #13 + FileName); end; end; Процесс CloudSync.exe копирует первые 4096 байт во временный файл с расширением .ads. Далее копирует оставшуюся часть файла с зашифрованным содержимым во временный файл. Далее сохраняет служебную информацию (заголовок из временного файла с расширением .ads) в ADS временного файла (:AlfaFileEncryptor). Далее перемещает временный файл в зеркальную папку. Еще одна техническая проблема: как сделать так, чтобы при копировании зашифрованных файлов из папки Google Диск в зеркальную папку они повторно не шифровались драйвером? Решение этого вопроса отображено кодом, благодаря которому при перемещении файла в контролируемую шифрованную папку драйвер не производит никаких действий с файлом и поэтому повторное шифрование файла не осуществляется: function TrimHeaderAndMoveFile(SyncIndex: Integer; FileNameFrom, FileNameTo: TFileName): Boolean; // FileNameFrom - имя файла с "правильным" заголовком // FileNameTo - имя файла в шифрованном каталоге // P.S. FileNameFrom и FileNameTo должны быть на 1-ом разделе var fs, fs1: TFileStream; fn: string; begin Result := False; // путь к временному файлу fn := GetTempFileName(SyncIndex, FileNameFrom); try try // открываем зашифрованный файл в облачной папке fs := TFileStream.Create(FileNameFrom, fmOpenRead); try try // создаем временный файл с расширением .ads для сохранения служебного заголовка fs1 := TFileStream.Create(fn + '.ads', fmCreate); try fs1.CopyFrom(fs, SIZE_OF_ATE_HEADER); // 4096 байт finally fs1.Free; end; except on E: Exception do WriteToLog('!!! TrimHeaderAndMoveFile: ' + E.Message + #13 + fn); end; try if fs.Size > SIZE_OF_ATE_HEADER then // если содержимое зашифрованного файла не пустое begin fs1 := TFileStream.Create(fn, fmCreate); try fs1.CopyFrom(fs, fs.Size - SIZE_OF_ATE_HEADER); // копируем содержимое зашифрованного файла из облака во временный файл finally fs1.Free; end; end else begin CreateEmptyFile(fn); // если нет содержимого, то создаем пустой временный файл end; except on E: Exception do WriteToLog('!!! TrimHeaderAndMoveFile: ' + E.Message + #13 + fn); end; finally fs.Free; end; WriteADS(fn, fn + '.ads', 'AlfaFileEncryptor'); // создаем ADS для временного файла и копируем туда содержимое временного файла с расширением .ads DeleteFile(fn + '.ads'); // удаляем временный файл с расширением .ads // Вызываем функцию проверки наличия файла в зеркальной папке из процесса CloudSync2.exe if RemoteIsFileExists(FileNameTo) then begin // Вызываем функцию удаления файла в зеркальной папке из процесса CloudSync2.exe RemoteDeleteFile(FileNameTo); end; // Перемещаем временный файл в зеркальную папку RenameFile(fn, FileNameTo); Result := True; except end; finally if FileExists(fn) then begin try DeleteFile(fn); except end; end; if FileExists(fn + '.ads') then begin try DeleteFile(fn + '.ads'); except end; end; end; end; 1.2 Если заголовка нет, считаем файл не зашифрованным. Процесс СloudSync2.exe копирует файл в зеркальную папку, после чего он автоматически шифруется драйвером. Не зашифрованный файл удаляется из папки Google Диск. Далее процесс CloudSync.exe копирует в папку Google Диск из зеркальной файл в зашифрованном виде, после чего он автоматически отправляется на “облако” и попадает к другим пользователям. 2. Файл копируется или редактируется в зеркальной папке CyberSafe Если новый файл копируется пользователем в зеркальную папку CyberSafe, он автоматически шифруется драйвером. При редактировании уже существующего файла в зеркальной папке он сохраняется на диск в зашифрованном виде также автоматически. Далее зашифрованный файл отправляется процессом CloudSync.exe в папку Google Диск со служебной информацией в заголовке и оттуда попадает на “облако”. Для правильной синхронизации и реагирования на изменения файлов в папках Google Диск и зеркальной, процессы CloudSync.exe и CloudSync2.exe производят мониторинг активности в этих папках и осуществляют соответствующие операции копирования, описанные выше.