Как зашифровать и расшифровать текст или файл в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе разработки конфигураций и внешних обработок на платформе 1С:Предприятие 7.7 часто возникает необходимость защитить конфиденциальные сведения: пароли подключения к внешним базам, учетные данные API или внешние файлы настроек. Разберем особенности реализации криптографических механизмов в среде 1С 7.7, изучим готовые алгоритмы на встроенном языке и проанализируем альтернативные способы защиты информации.

Ограничения платформы 1С 7.7 при работе с шифрованием

Прежде чем приступать к программной реализации, выясним ключевые архитектурные ограничения платформы 1С 7.7:

  1. Отсутствие встроенных побитовых операций: Во встроенном языке 1С 7.7 нет базовых бинарных операторов (XOR, AND, OR, битовых сдвигов). Для их выполнения приходится подключать системный COM-объект MSScriptControl.ScriptControl с языком VBScript или использовать сторонние библиотеки.
  2. Особенности строкового типа: Строки в 1С 7.7 являются нуль-терминированными (в кодировке Windows-1251). Если в процессе шифрования байта получается нулевое значение (Симв(0)), строка обрезается. Поэтому зашифрованный бинарный поток необходимо обязательно упаковывать в безопасный формат (например, шестнадцатеричный вид — Hex).
  3. Скорость выполнения: Интерпретатор встроенного языка 1С 7.7 выполняет побайтовые преобразования относительно медленно, поэтому программные алгоритмы на встроенном языке подходят только для небольших объемов данных (пароли, короткие строки конфигурации).

Алгоритм шифрования на встроенном языке 1С 7.7

Рассмотрим реализацию симметричного шифрования на основе псевдослучайных перестановок (S-блока) и побайтовой операции XOR. Для выполнения логического сложения по модулю 2 используется MSScriptControl.ScriptControl.

Разберем базовую функцию преобразования строки по ключу:


// Функция шифрует или дешифрует набор символов с помощью S-Блока, сформированного на основе ключа.
// Строчка - Строка. Набор символов для преобразования.
// Ключ - Строка. Набор символов для формирования S-Блока.
Функция СтрКодироватьСтрокуВнутр(Строчка, Ключ) Экспорт
    Перем масТемп[254], масSБлок[254];
    Перем чисДлинаКлюча, чисДлинаТекста, х, у, чисТемп, ЧисБайт, Ответ, ч;
    Перем Shell_funcXOR;
    
    Shell_funcXOR = СоздатьОбъект("MSScriptControl.ScriptControl");
    Shell_funcXOR.Language = "VBScript";
    Shell_funcXOR.AddCode("function intXOR(x, y) | intXOR = x xor y |end function");
    
    // Инициализация данных для формирования S-Блока
    чисДлинаКлюча = СтрДлина(Ключ);
    у = 0;
    Для х = 1 По 254 Цикл
        у = у + 1;
        у = ?(у > чисДлинаКлюча, 1, у);
        масТемп[х] = КодСимв(Сред(Ключ, у, 1));
        масSБлок[х] = х - 1;
    КонецЦикла;
    
    // Формирование S-Блока
    у = 0;
    Для х = 1 По 254 Цикл
        у = (у + масТемп[х] + масSБлок[х]) % 254 + 1;
        чисТемп = масSБлок[х];
        масSБлок[х] = масSБлок[у];
        масSБлок[у] = чисТемп;
    КонецЦикла;
    
    // Преобразование исходного текста
    чисДлинаТекста = СтрДлина(Строчка);
    у = 0;
    ч = 0;
    Ответ = "";
    Для х = 1 По чисДлинаТекста Цикл
        чисБайт = КодСимв(Сред(Строчка, х, 1));
        у = (у + 1) % 254 + 1;
        ч = (ч + масSБлок[у]) % 254 + 1;
        чисТемп = масSБлок[у];
        масSБлок[у] = масSБлок[ч];
        масSБлок[ч] = чисТемп;
        чисТемп = масSБлок[(масSБлок[у] + масSБлок[ч]) % 254 + 1];
        чисБайт = Число(Shell_funcXOR.Run("intXOR", чисБайт, чисТемп));
        Ответ = Ответ + Симв(чисБайт);
    КонецЦикла;
    
    Возврат Ответ;
КонецФункции

Шестнадцатеричное кодирование (Hex)

Поскольку результат битового шифрования может содержать непечатные и нулевые символы, обязательно преобразуем результат в шестнадцатеричную строку (Hex) и обратно:


// Конвертирует строку в её шестнадцатеричное представление
Функция СтрКонвертироватьВШестнадцатиричнуюСтроку(Строчка) Экспорт
    Перем Результат, ДлинаСтроки, Номер, Символ, Цифра;
    ДлинаСтроки = СтрДлина(Строчка);
    Результат = "";
    Для Номер = 1 По ДлинаСтроки Цикл
        Символ = КодСимв(Сред(Строчка, Номер, 1));
        Цифра = Цел(Символ / 16);
        Результат = Результат + ?(Цифра < 10, Строка(Цифра), Симв(КодСимв("A") + Цифра - 10));
        Цифра = Цел(Символ % 16);
        Результат = Результат + ?(Цифра < 10, Строка(Цифра), Симв(КодСимв("A") + Цифра - 10));
    КонецЦикла;
    Возврат Результат;
КонецФункции

// Конвертирует строку из шестнадцатеричного представления в исходную строку
Функция СтрКонвертироватьИзШестнадцатиричнойСтроки(Строчка) Экспорт
    Перем Результат, ДлинаСтроки, Номер, Символ, Цифра;
    ДлинаСтроки = Цел(СтрДлина(Строчка) / 2);
    Результат = "";
    Для Номер = 1 По ДлинаСтроки Цикл
        Символ = КодСимв(Сред(Строчка, Номер * 2 - 1, 1));
        Символ = ?(Символ < КодСимв("A"), Символ - КодСимв("0"), Символ - КодСимв("A") + 10);
        Цифра = 16 * Символ;
        Символ = КодСимв(Сред(Строчка, Номер * 2, 1));
        Символ = ?(Символ < КодСимв("A"), Символ - КодСимв("0"), Символ - КодСимв("A") + 10);
        Цифра = Цифра + Символ;
        Результат = Результат + Симв(Цифра);
    КонецЦикла;
    Возврат Результат;
КонецФункции

Функции шифрования и дешифрования с рандомизацией длины

Для предотвращения частотного анализа коротких строк (например, паролей) добавим автоматическое дополнение строки солью до минимальной заданной длины:


// Функция шифрует строку на основе ключа с добавлением соли
Функция СтрКодироватьСтроку(Знач Строчка, Ключ, МинимальнаяДлина = 20) Экспорт
    Перем Соль;
    Соль = _GetPerformanceCounter % 1000;
    Строчка = Формат(СтрДлина(Строчка), "Ч04") + Строчка;
    Пока СтрДлина(Строчка) < МинимальнаяДлина Цикл
        Строчка = Строчка + СокрЛП(_IdToStr(Соль));
        Соль = (Соль * Соль) % 1000;
    КонецЦикла;
    Возврат СтрКонвертироватьВШестнадцатиричнуюСтроку(СтрКодироватьСтрокуВнутр(Строчка, Ключ));
КонецФункции

// Функция расшифровывает шестнадцатеричную строку
Функция СтрРаскодироватьСтроку(Строчка, Ключ) Экспорт
    Перем Результат;
    Результат = СтрКодироватьСтрокуВнутр(СтрКонвертироватьИзШестнадцатиричнойСтроки(Строчка), Ключ);
    Возврат Сред(Результат, 5, Число(Лев(Результат, 4)));
КонецФункции

Альтернативные и системные способы защиты данных

Если требуется шифровать большие текстовые файлы или целые массивы данных, возможностей чистого встроенного языка 1С 7.7 будет недостаточно по скорости. В таких случаях применяются следующие методы:

  1. Системный Windows CryptoAPI / CAPICOM: Использование системных библиотек через COM-интерфейс позволяет выполнять криптографические операции (AES, 3DES) на уровне операционной системы с максимальной скоростью без нагрузки на интерпретатор 1С.
  2. Внешние компоненты (DLL): Создание или подключение внешней компоненты (на C++ или Delphi), выполняющей побайтовое шифрование нативной машинной инструкцией.
  3. Консольные криптоутилиты с потоковым выводом: Дешифрование файлов можно производить без промежуточного сохранения открытого текста на диск — запускать утилиту через объект WScript.Shell (метод Exec()) и считывать результат напрямую из потока standard output (StdOut).
  4. Защита дискового пространства: Если цель — защита всей базы от несанкционированного копирования, целесообразно использовать прозрачное шифрование разделов (BitLocker, специализированные дисковые контейнеры) и терминальный доступ с ограничением прав пользователей.
← На главную