Может использоваться в мобильных приложениях для повышения безопасности.
Код приведён исключительно в ознакомительных целях, для создания криптосредств требуется лицензия ФСБ.
https://www.rfc-editor.org/rfc/rfc2104
Функция HMAC256(Знач СекретныйКод, Знач Сообщение) Экспорт РазмерБлока = 64; Если СекретныйКод.Размер() > РазмерБлока Тогда СекретныйКод = ПолучитьХэшСумму(СекретныйКод); КонецЕсли;; ПустойБлок = ПолучитьДвоичныеДанныеИзСтроки(""); ПерваяЧасть = ЗаполнитьБлокКонстантой(СекретныйКод, РазмерБлока, "0x00"); ВтораяЧасть = ЗаполнитьБлокКонстантой(ПустойБлок, РазмерБлока, "0x36"); ТретьяЧасть = ПрименитьБинарноеПобитовоеИсключающееИЛИ(ПерваяЧасть, ВтораяЧасть); ЧетвертаяЧасть = ЗаполнитьБлокКонстантой(ПустойБлок, РазмерБлока, "0x5C"); ПятаяЧасть = ПрименитьБинарноеПобитовоеИсключающееИЛИ(ПерваяЧасть, ЧетвертаяЧасть); СклеиваемыеДанные = Новый Массив(); СклеиваемыеДанные.Добавить(ТретьяЧасть); СклеиваемыеДанные.Добавить(Сообщение); ШестаяЧасть = СоединитьДвоичныеДанные(СклеиваемыеДанные); СклеиваемыеДанные = Новый Массив(); СклеиваемыеДанные.Добавить(ПятаяЧасть); СклеиваемыеДанные.Добавить(ПолучитьХэшСумму(ШестаяЧасть)); СедьмаяЧасть = СоединитьДвоичныеДанные(СклеиваемыеДанные); Возврат ПолучитьХэшСумму(СедьмаяЧасть); КонецФункции Функция ПолучитьХэшСумму(Знач Данные) ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.SHA256); ХешированиеДанных.Добавить(Данные); Возврат ХешированиеДанных.ХешСумма; КонецФункции Функция ЗаполнитьБлокКонстантой(Знач ИсходныеДанные, Знач РазмерБлока, Знач hexКонстанта) ЧтениеДанных = Новый ЧтениеДанных(ИсходныеДанные); Буфер = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных(); ЧтениеДанных.Закрыть(); ПотокВПамяти = Новый ПотокВПамяти(); ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти); Если Буфер.Размер > 0 Тогда ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(Буфер); КонецЕсли; //Заполним константой до конца блока decКонстанта = ЧислоИзШестнадцатеричнойСтроки(hexКонстанта); Для Итерация = Буфер.Размер + 1 По РазмерБлока Цикл ЗаписьДанных.ЗаписатьБайт(decКонстанта); КонецЦикла; ЗаписьДанных.Закрыть(); Возврат ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные(); КонецФункции Функция ПрименитьБинарноеПобитовоеИсключающееИЛИ(Знач ПерваяЧастьДанных, Знач ВтораяЧастьДанных) ЧтениеДанных = Новый ЧтениеДанных(ПерваяЧастьДанных); ПервыйБуфер = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных(); ЧтениеДанных.Закрыть(); ЧтениеДанных = Новый ЧтениеДанных(ВтораяЧастьДанных); ВторойБуфер = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных(); ЧтениеДанных.Закрыть(); ПотокВПамяти = Новый ПотокВПамяти(); ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти); Если ПервыйБуфер.Размер > ВторойБуфер.Размер Тогда ПервыйБуфер.ЗаписатьПобитовоеИсключительноеИли(0, ВторойБуфер, ВторойБуфер.Размер); ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ПервыйБуфер); Иначе ВторойБуфер.ЗаписатьПобитовоеИсключительноеИли(0, ПервыйБуфер, ПервыйБуфер.Размер); ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ВторойБуфер); КонецЕсли; ЗаписьДанных.Закрыть(); Возврат ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные(); КонецФункции ПотокВПамятиСекретныйКод = Новый ПотокВПамяти; ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамятиСекретныйКод); ЗаписьДанных.ЗаписатьСимволы("СекретныйКод", КодировкаТекста.UTF8); ПотокВПамятиСообщение = Новый ПотокВПамяти; ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамятиСообщение); ЗаписьДанных.ЗаписатьСимволы("Сообщение", КодировкаТекста.UTF8); Подпись = HMAC256(ПотокВПамятиСекретныйКод.ЗакрытьИПолучитьДвоичныеДанные(), ПотокВПамятиСообщение.ЗакрытьИПолучитьДвоичныеДанные())