Подпись данных алгоритмами SHA + AES собственным модулем

03.09.21

Разработка - Защита ПО и шифрование

Реализация подписи данных ключом длиной 256 бит алгоритмами SHA-256 + AES-256 без использования внешних компонент, zip-файлов, обращения к диску или БД и без привязки к ОС.

Скачать файлы

Наименование Файл Версия Размер
AES_SHA_v1.0
.epf 29,22Kb
9
.epf 29,22Kb 9 Скачать
(ненужное дополнение) Список модулей криптографии Windows
.epf 8,89Kb
1
.epf 8,89Kb 1 Скачать

Предлагаемая обработка является продолжением другой, опубликованной здесь ранее:

Быстрый алгоритм шифрования AES ECB 128/192/256

Подпись данных и 1С

Платформа 1С позволяет подписать данные средствами платформы. Для этого необходимо использовать объект МенеджерКриптографии. Данный объект обеспечивает разработчика самым серьёзным инструментом по защите данных. Состав доступных алгоритмов определяется операционной системой и дополнительно установленными в ней модулями криптографии.

Для примера - ниже состав доступных алгоритмов с первых двух попавшихся ОС:

Таким образом перед разработчиком богатый выбор. Однако, обратите внимание - алгоритма AES в списке нет (128, 192, 256 .. никакого). Выдержка из википедии:

В июне 2003 года Агентство национальной безопасности США постановило, что шифр AES является достаточно надёжным, чтобы использовать его для защиты сведений, составляющих государственную тайну (англ. classified information). Вплоть до уровня SECRET было разрешено использовать ключи длиной 128 бит, для уровня TOP SECRET требовались ключи длиной 192 и 256 бит[8].

То есть не сказать, что он какой-то ничтожный.

Обмен данными между узлами через публичные каналы связи

Подпись данных применяется при авторизации данных в API-запросах. Суть метода заключается в том, чтобы подписать передаваемые данные в пакете и добавить отпечаток подписи в заголовок запроса, например в "X-API-Key". Через это обеспечивается дополнительная защита от подмены запросов.

Даже, если у злоумышленника будут данные авторизации пользователя, ему будет сложно подобрать ключ подписи.

Использование в этих целях стандартных средств требует дополнительных усилий:

1. Необходимо развернуть систему сертификатов на всех узлах.

2. Сертификаты нужно где-то получать и регулярно обновлять на всех узлах (устанавливать новые). Можно использовать самоподписанные сертификаты действием в 1 год, но такой вариант нежелателен.

3. Если вы "прохлопаете" сертификат - обмен остановится. Конечно, в случае, когда перед вами стоят очень высокие требования безопасности - это даже хорошо.

А можно что-то попроще?

Действительно - а если я просто хочу на всякий случай добавить подпись данных между своими узлами? Мне бы хотелось иметь один пароль или ключ, раздать его надёжным каналом по всем узлам и пользоваться. Ну там периодически менять его и всё. И желательно, чтоб это всё быстро работало.

Ответ: можно, но понадобится предлагаемая обработка.

Как работает подписание в предлагаемой обработке?

Достаточно просто - получаем хэш и шифруем:

1. На входе получаем подписываемые данные в виде строки или двоичных данных.

2. Получаем из них хэш SHA-256.

3. Далее получаем случайное число, 64 бит. Заполняем им выходной буфер (повторами).

4. Далее получаем отметку времени и XOR-им с серединкой выходного буфера.

5. XOR-им хэш с концом выходного буфера.

6. Шифруем всё секретным ключом.

Поясню пункты 1-5: На выходе получается такая цепочка: случайное число, далее XOR-енная отметка времени и далее XOR-енный хэш. Это нужно для того, чтобы было неизвестно, что зашифровано. Так сложнее организовать атаку с целью получения секретного ключа.

Для описанных ранее целей этого хватит с избытком.

Точно код подписи выглядит вот так:

// Функция - Подписать
//
// Параметры:
//  Данные	 - ДвоичныеДанные, Строка	 - Подписываемые данные
//  Ключ256	 - ДвоичныеДанные	 - Ключ длинной 256 бит
// 
// Возвращаемое значение:
//  ДоичныеДанные - Отпечаток подписи
//
Функция Подписать(Данные, Ключ256) Экспорт
	
	// Получаем хэш SHA-256
	Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
	Хеш.Добавить(Данные);
	SHA256 = Хеш.ХешСумма;
	
	ЧтениеХэш	= Новый ЧтениеДанных(SHA256);
	БуферХэш	= ЧтениеХэш.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеХэш.Закрыть();
	
	// Формируем данные подписи:
	// R = случайное число 8 байт
	// D = время подписи в секундах XOR R
	// X = Хэш данных XOR (R + R + R + R + R)             
	ВремяСозданияАлгоритма = 63739655820000; // Дата("20201030115700") - Дата("00010101") UTC
	Сейчас = ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяСозданияАлгоритма;
	ГенераторСлучайныхЧисел = Новый ГенераторСлучайныхЧисел(Сейчас % 4294967295);
	Ч1 = ГенераторСлучайныхЧисел.СлучайноеЧисло();
	Ч2 = ГенераторСлучайныхЧисел.СлучайноеЧисло();
	
	Буфер = Новый БуферДвоичныхДанных(48);
	Буфер.ЗаписатьЦелое32(0, Ч1);
	Буфер.ЗаписатьЦелое32(4, Ч2);
	
	Буфер_R = Буфер.Скопировать();
	
	Буфер.ЗаписатьЦелое64(8, Сейчас);
	Буфер.Записать(16, БуферХэш, 32);
	
	Буфер.ЗаписатьПобитовоеИсключительноеИли(8, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(16, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(24, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(32, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(40, Буфер_R, 8);
	
	Поток			= Новый ПотокВПамяти(Буфер);
	ДанныеПодписи	= Поток.ЗакрытьИПолучитьДвоичныеДанные();
	
	Возврат ЗашифроватьAES(ДанныеПодписи, Ключ256);
КонецФункции // Подписать

При проверке подписи всё выполняется в обратном порядке:

// Функция - Проверить подпись
//
// Параметры:
//  ПодписанныеДанные	 - Строка, ДвоичныеДанные	 - Подписанные данные
//  ДанныеОтпечатка		 - ДвоичныеДанные	 - Отпечаток подписи
//  Ключ256				 - ДвоичныеДанные	 - Ключ подписи размером 256 бит
// 
// Возвращаемое значение:
//  Структура - Результат сверки подписи. Содержит структуру с полями:
//  * ПодписьВерна - Булево - Результат проверки. Истина - всё в порядке.
//	* ДатаПодписи - Дата - Дата подписания
//	* ДоляСекунды - Число - Доля секунды, в которую происходило подписание.
//
Функция ПроверитьПодпись(ПодписанныеДанные, ДанныеОтпечатка, Ключ256) Экспорт
	
	// Получаем хэш SHA-256
	Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
	Хеш.Добавить(ПодписанныеДанные);
	SHA256 = Хеш.ХешСумма;
	
	ЧтениеХэш	= Новый ЧтениеДанных(SHA256);
	БуферХэш	= ЧтениеХэш.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеХэш.Закрыть();
	
	// Расшифровываем
	ДанныеПодписи	= РасшифроватьAES(ДанныеОтпечатка, Ключ256);
	ЧтениеПодписи	= Новый ЧтениеДанных(ДанныеПодписи);
	БуферПодписи	= ЧтениеПодписи.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеПодписи.Закрыть();
	
	// Снимаем XOR
	Буфер = Новый БуферДвоичныхДанных(48);
	Буфер.Записать(0, БуферПодписи, 48);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(8, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(16, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(24, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(32, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(40, БуферПодписи, 8);
	
	// Получаем результат
	Результат = Новый Структура("ПодписьВерна,ДатаПодписи,ДоляСекунды");
	
	Буфер.ЗаписатьПобитовоеИсключительноеИли(16, БуферХэш, 32);
	КонтрольноеЧисло = Буфер.ПрочитатьЦелое64(16) + Буфер.ПрочитатьЦелое64(24) + Буфер.ПрочитатьЦелое64(32) + Буфер.ПрочитатьЦелое64(40);
	Результат.ПодписьВерна = (КонтрольноеЧисло = 0);
	
	Если Результат.ПодписьВерна Тогда
		ВремяСозданияАлгоритма	= 63739655820000; // Дата("20201030115700") - Дата("00010101") UTC
		ВремяПодписи			= Буфер.ПрочитатьЦелое64(8) + ВремяСозданияАлгоритма;
		Результат.ДатаПодписи	= Дата("00010101") + Цел(ВремяПодписи / 1000);
		Результат.ДоляСекунды	= ВремяПодписи % 1000;
	КонецЕсли;	
	
	Возврат Результат;
КонецФункции // ПроверитьПодпись

Тесты

Обработка тестировалась на платформе 1С:Предприятие 8.3 (8.3.16.1502).

Сеанс выполнялся на ядре с тактовой частотой 1,58 ГГц (максимальная 3,3 ГГц).

За каждую итерацию выполняется подпись и проверка подписи - то есть два действия. В качестве подписываемых данных генерится строка, кратная одному блоку AES (16 байт): от 16 до 512 байт.

Для каждой длины делается 10 итераций и берётся среднее время.

Процедура тестирования:

&НаСервере
Процедура ТестСкоростиНаСервере()
	
	ОбработкаОбъект	= РеквизитФормыВЗначение("Объект");
	СчётчикПаролей	= 1;
	ИсходнаяСтрока	= "";
	
	Для ЧислоБлоков = 1 по 32 Цикл
		
		Данные			= ПолучитьДанные(ЧислоБлоков);
		СреднееВремя	= 0;
		
		Для НомерИтерации = 1 по 10 Цикл
			
			Ключ256			= ПолучитьКлюч256(Формат(СчётчикПаролей, ""));
			СчётчикПаролей	= СчётчикПаролей + 1;
			
			Время1 = ТекущаяУниверсальнаяДатаВМиллисекундах(); // СТАРТ!
			
			Результат		= ОбработкаОбъект.Подписать(Данные, Ключ256);
			ИсходныеДанные	= ОбработкаОбъект.ПроверитьПодпись(Данные, Результат, Ключ256);
			
			Время2 = ТекущаяУниверсальнаяДатаВМиллисекундах(); // СТОП!
			
			СреднееВремя	= СреднееВремя + Время2 - Время1;
			
		КонецЦикла;
		
		ТекстСообщения = СтрШаблон(
			"%1;%2"
			,Формат(ЧислоБлоков, "ЧН=; ЧГ=")
			,Формат(СреднееВремя / 10, "ЧРД=,; ЧН=; ЧГ=")
		);
		Сообщить(ТекстСообщения);
	КонецЦикла;
	
КонецПроцедуры

Результат:

См. также

Запрет глобального поиска в конфигурации

Защита ПО и шифрование Платформа 1С v8.3 1С:Бухгалтерия 3.0 Абонемент ($m)

Представляю вам микрорасширение, которое запрещает глобальный поиск по вашей конфигурации.

1 стартмани

09.02.2023    2223    9    aximo    4    

2

Как защитить pdf файл

Защита ПО и шифрование Абонемент ($m)

Для установки защиты pdf документа, полученного в 1С, написано консольное приложение на c#., использующее одну зависимость pdfSharp.dll. В результате работы приложения ограничены операции над документом и записаны метаданные. С помощью аргументов командной строки можно управлять работой приложения.

2 стартмани

30.01.2023    1657    1    olevlasam    3    

3

Универсальный синтаксический анализатор ASN.1 для декодирования .key, .cer, .der, .p7m, .p7s, .crt, .pem

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Универсальный синтаксический анализатор ASN.1, который может декодировать любую допустимую структуру ASN.1 DER или BER, независимо от того, закодирована ли она в кодировке Base64 (распознаются необработанные base64, защита PEM и begin-base64) или в шестнадцатеричном кодировании.

1 стартмани

04.12.2022    2983    12    keyn5565`    0    

13

Шифрование строки на основе мастер-пароля в 1С Предприятие 8.3.19

Защита ПО и шифрование Платформа 1С v8.3 Абонемент ($m)

Демонстрация возможностей шифрования строки на основе мастер-пароля в 1С Предприятие 8.3.19. AES без zip файла, RSA, PKDF2. (c использованием библиотеки С# через com).

2 стартмани

31.08.2022    3830    7    vit59    2    

6

Обфускатор байт-кода

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Обработка, позволяющая запутывать и шифровать байт-код, поставлять модули без исходных текстов и т.д. Протестировано на платформе 8.3.23.1739.

10 стартмани

16.06.2022    10293    79    ZhokhovM    12    

40

Как уберечь конструкторскую документацию от воровства конкурентами?

Защита ПО и шифрование Платформа 1С v7.7 Платформа 1С v8.3 Абонемент ($m)

Как уберечь конструкторскую документацию от воровства конкурентами? Недавно столкнулся с этой проблемой. Заказчик серьёзно обеспокоен утечкой информации о конструкторских разработках в адрес конкурентов, за счет подкупа исполнителей, занимающихся производством по конструкторской документации, операторов технологического оборудования и обрабатывающих центров по изготовлению деталей и сборочных единиц.

2 стартмани

09.03.2022    5654    3    ge_ni    9    

2

Защита конфигураций, обработок, расширений 1С онлайн, управление версиями

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Система построена на веб платформе, все управление происходит на сайте в личном кабинете пользователя.

1 стартмани

27.12.2021    4556    2    idm80    11    

9
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. altu71 02.11.20 16:57 Сейчас в теме
Чем отличаются две предлагаемые к скачиванию обработки?
2. 1div0 80 03.11.20 07:18 Сейчас в теме
(1)
Чем отличаются две предлагаемые к скачиванию обработки?


Спасибо, я не обратил внимания, что названия в итоге получились одинаковые - я ещё путаюсь в миллионе полей, которые надо заполнить, чтобы выложить файл. Поправил в статье.

Верхняя обработка - это то что нужно: AES_ESB_v2.1, содержит функции подписи и проверки подписи, и быструю реализацию алгоритма AES.

Вторая обработка - ненужное дополнение, я её написал специально для статьи. Может быть кому-то понадобится или будет интересно. Вот тоже можно скачать.
3. 1div0 80 03.11.20 07:20 Сейчас в теме
(1) Есть ещё скриншот второй обработки:
5. 1div0 80 03.11.20 07:22 Сейчас в теме
(1) Хм.. необычно, что новые ответы сначала появляются сверху.
4. пользователь 03.11.20 07:21
Сообщение было скрыто модератором.
...
6. SizovE 262 16.02.21 15:48 Сейчас в теме
Подскажи, пожалуйста, а зачем делать к SHA256 еще 5 пунктов, ради чего? Разве как-то можно получить данные из SHA256?
Недостаточно ли разве что-то типа такого ЗашифроватьAES(SHA256, Ключ256)
И еще вопрос, а почему не сделать: SHA256(Соль + передаваемые данные) и сверить тоже самое на точке получатель?
Соль (или ключ256 в данном случае) известна только отправителю и получателю.
7. 1div0 80 17.02.21 06:30 Сейчас в теме
(6) ЗашифроватьAES(SHA256, Ключ256) - потому что это очевидное решение. Допустим злоумышленник предполагает именно такую схему. Перехватываем любое сообщение, получаем SHA256. Далее включаем видеокарту и перебираем Ключ256, пока не совпадёт равенство:
ЗашифроватьAES(SHA256, Ключ256) = SHA256.

Поэтому усложняем. Вы предлагаете добавлять Соль - и это правильно. Но она для всех сообщений получается одна и та же. И её тоже можно получить сравнивая хэши разных сообщений. К тому же это ещё дополнительный ключ, что снижает удобство.

Поэтому ещё усложняем. В статье мы получаем случайную соль при каждой подписи. Только применяем соль не на расчёт хэша, что хуже, а на шифр.

С получением случайных чисел есть проблемы, поэтому я дополнительно порчу результат генератора данными об отметке времени. Поскольку нам известен ключ и само сообщение, то мы можем на стороне получателя восстановить буфер с солью и отметкой времени просто расшифровав и применив XOR между хэшем и буфером. Отметку времени я поместил в середину буфера, чтобы зная не испорченный начало и конец можно было получить значение этой отметки. Таким образом на выходе есть не только информация о том - совпадает или нет, но и дополнительная информация о том, когда подпись поставлена.

Со стороны злоумышленника надо немного больше заморочиться и подобрать кроме ключа ещё 32-битное число. То есть объём перебора = 256 + 32 = 288 бит. Ну и существенно увеличено время на каждую итерацию перебора. Если использовать генератор получше, то можно добавить ещё 64 бита перебора. Можно ещё увеличить стойкость, выкинув отметку времени и заполняя случайными данными начальный буфер, тогда объём перебора будет 256 + 256.
8. SizovE 262 17.02.21 16:26 Сейчас в теме
(7) Я так понимаю, Вы хотите поставить защиту от чужих запросов, выполнять запросы только свои.
Ключ для AES разве так просто подобрать? Он же достаточно длинный будет.

Разве так просто получить соль сравнения SHA256(Соль + передаваемые данные) разных сообщений? Вроде как SHA256 гарантирует высокую сложность такой задачки? Учитывая, что это узлы все ваши, и передаваемые данные нельзя "подгонять" (хотя мне кажется даже в этом случае вычислить соль не так уж и просто)

А ведь в Вашем случае, если я знаю Ваш алгоритм, то соль для меня не является уже "случайной"?

Еще вопросик - Ваш алгоритм AES получает такой же результат как онлайн алгоритмы - https://encode-decode.com/aes-256-ecb-encrypt-online/, если ДА, то возьму себе Вашу обработку ) Кстати, она есть за 1 стартмани и за 2 - обе одинаково работают для задачи шифровки и расшифровки?
9. 1div0 80 17.02.21 18:10 Сейчас в теме
(8) Данная реализация получает такой же результат, как и другие его реализации на онлайн-ресурсах, например этом.

Верхняя обработка - это то что нужно: AES_ESB_v2.1, содержит функции подписи и проверки подписи, и быструю реализацию алгоритма AES.

Вторая обработка - ненужное дополнение, я её написал специально для статьи. Может быть кому-то понадобится или будет интересно. Вот тоже можно скачать.

Про соль и прочее - к сказанному выше мне нечего дополнить.
10. kuza2000 203 08.06.23 11:10 Сейчас в теме
(7)
ЗашифроватьAES(SHA256, Ключ256) - потому что это очевидное решение.


И это хорошо, потому что:
Если защита, обеспечиваемая алгоритмом, основана на сохранении в тайне самого алгоритма, то это ограниченный алгоритм.
Ограниченные алгоритмы представляют некоторый исторический
интерес, но не соответствуют современным стандартам.
Ограниченные алгоритмы не допускают эффективного контроля или стандартизации. Каждая группа пользователей должна
использовать собственный уникальный алгоритм. Такие группы
не могут использовать открытые аппаратные или программные
продукты – злоумышленник может приобрести такой же продукт
и раскрыть алгоритм. Этим группам приходится разрабатывать и
реализовывать собственные алгоритмы.
Несмотря на указанные фундаментальные недостатки, ограниченные алгоритмы необычайно популярны в приложениях с
низким уровнем защиты. Пользователи либо не осознают проблем,
связанных с безопасностью своих систем, либо слабо заботятся о
решении проблемы.
(С) Брюс Шнайер, Прикладная криптография
Показать


Далее включаем видеокарту и перебираем Ключ256, пока не совпадёт равенство:
ЗашифроватьAES(SHA256, Ключ256) = SHA256.

Для этого потребуется время, в миллионы раз превышающее время существования вселенной)) У меня получилось значение 10 в 50 степени раз) Может и ошибся немного, но это ничего не меняет...

Ваш алгоритм так же подвержен этому методу атаки - брутфорсу. Но проанализировать его уже сложнее, поэтому он дает меньшую гарантию криптостойкости. В общем, я не увидел ни одной причины для такого усложнения алгоритма.

Недавно потребовалось подписывать сообщения, которые формируются и возвращаются в одну и ту же базу. Сделал просто, как тут уже предложили. В сообщение добавил SHA256 от текста сообщения и секретной соли. Разумеется, соль нужно выбрать не меньше 256 бит - это где-то 32-128 символов, в зависимости от набора. Больше тут ничего не нужно
Оставьте свое сообщение