Симметричное шифрование AES-256 встроенными средствами платформы 1С
Иногда требуется хранить в базе чувствительную информацию в зашифрованном виде,
наиболее частый пример - пароли. Также рекомендуется шифровать вообще все
передаваемые данные при написании нетиповых обменов, особенно если они содержат
обнаженку персональные данные или финансовые операции.
В платформе 1С в явном виде отсутствуют средства симметричного шифрования, но зато есть шифрование на основе инфраструктуры открытого ключа (PKI). Реализацию PKI для простых задач типа шифрования пароля или пакета обмена является избыточно сложным, как с точки зрения написания, так и с точки зрения дальнейшего администрирования. Поэтому многие пишут самодельные алгоритмы, чаще всего сомнительного качества защиты.
На самом деле готовое, надежное и качественное симметричное шифрование в платформе 1С есть, только спрятано оно в объектах ЗаписьZipФайла и ЧтениеZipФайла. Ниже шпаргалка с готовыми функциями.
Шифрование строки или двоичных данных в AES-256
// Функция - Зашифровать при помощи алгоритма симметричного шифрования AES-256
//
// Параметры:
// Данные - Строка - Предмет шифрования (пустой недопустим)
// Пароль - Строка - Пароль шифрования (пустой недопустим)
// ВходСтрока - Булево - Истина: в параметре Данные находится Строка
// Ложь: в параметре Данные находится адрес временного
// хранилища, содержащего ДвоичныеДанные
// ВыходBase64 - Булево - Истина: хотим результат типа Строка, в кодировке Base64
// Ложь: хотим результат типа Строка, в котором находится
// адрес временного хранилища, содержащего ДвоичныеДанные
// Возвращаемое значение: Строка (адрес временного хранилища или строка Base64)
//
Функция Зашифровать(Данные, Пароль, ВходСтрока = Истина, ВыходBase64 = Истина) Экспорт
Если Не ЗначениеЗаполнено(Данные) Или Не ЗначениеЗаполнено(Пароль) Тогда
Возврат Неопределено;
КонецЕсли;
ПутьФайла = ПолучитьИмяВременногоФайла();
Если ВходСтрока Тогда
ЗаписьТекста = Новый ЗаписьТекста(ПутьФайла);
ЗаписьТекста.Записать(Данные);
ЗаписьТекста.Закрыть();
Иначе
ДД = ПолучитьИзВременногоХранилища(Данные);
ДД.Записать(ПутьФайла);
КонецЕсли;
Zip = Новый ЗаписьZipФайла();
Zip.Добавить(ПутьФайла);
Д = Zip.ПолучитьДвоичныеДанные(
Пароль,,
МетодСжатияZip.BZIP2,
УровеньСжатияZip.Оптимальный,
МетодШифрованияZip.AES256
);
УдалитьФайлы(ПутьФайла);
Если ВыходBase64 Тогда
Возврат Base64Строка(Д);
Иначе
Возврат ПоместитьВоВременноеХранилище(Д);
КонецЕсли;
КонецФункции
Дешифрование данных AES-256
// Функция - Расшифровать данные ранее зашифрованные при помощи функции Зашифровать()
//
// Параметры:
// Данные - Строка - Адрес временного хранилища для зашифрованных ДвоичныхДанных
// или строка в формате Base64 (пустой недопустим)
// Пароль - Строка - Пароль дешифрования (пустой недопустим)
// ВходBase64 - Булево - Истина: в параметре Данные находится Строка Base64
// Ложь: в параметре Данные находится адрес временного
// хранилища, содержащего ДвоичныеДанные
// ВыходСтрока - Булево - Истина: ожидаем результат типа Строка с расшифрованными данными
// Ложь: ожидаем результат типа Строка, в котором находится
// адрес временного хранилища, содержащего ДвоичныеДанные
//
// Возвращаемое значение: Строка (адрес временного хранилища для расшифрованных ДвоичныхДанных
// или расшифрованная строка)
//
Функция Расшифровать(Данные, Пароль, ВходBase64 = Истина, ВыходСтрока = Истина) Экспорт
Если Не ЗначениеЗаполнено(Данные) Или Не ЗначениеЗаполнено(Пароль) Тогда
Возврат Неопределено;
КонецЕсли;
Поток = Новый ПотокВПамяти();
ДД = ? (ВходBase64, Base64Значение(Данные), ПолучитьИзВременногоХранилища(Данные));
ДД.Записать(Поток);
Каталог = КаталогВременныхФайлов();
Zip = Новый ЧтениеZipФайла(Поток, Пароль);
Если Zip.Элементы.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Файл = Zip.Элементы[0];
Zip.Извлечь(Файл, Каталог, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
Zip.Закрыть();
ПолноеИмяФайла = Каталог + ПолучитьРазделительПутиСервера() + Файл.Имя;
Если ВыходСтрока Тогда
ЧтениеТекста = Новый ЧтениеТекста(ПолноеИмяФайла);
Результат = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
Иначе
ДД = Новый ДвоичныеДанные(ПолноеИмяФайла);
Результат = ПоместитьВоВременноеХранилище(ДД);
КонецЕсли;
УдалитьФайлы(ПолноеИмяФайла);
Возврат Результат;
КонецФункции