новое событие
Информационный поток
Задания вакансии материалы разработки сообщения форума

Ознакомительный упрощенный пример функции HMAC256 для цифровой подписи запросов HTTP.

  • Добавить свою публикацию
  • для этого требуется регистрация

Может использоваться в мобильных приложениях для повышения безопасности.
Код приведён исключительно в ознакомительных целях, для создания криптосредств требуется лицензия ФСБ.

https://www.rfc-editor.org/rfc/rfc2104

 

Функция HMAC256(Знач СекретныйКод, Знач Сообщение) Экспорт
		
	РазмерБлока = 64;
	
	Если СекретныйКод.Размер() > РазмерБлока Тогда	
		СекретныйКод = ПолучитьХэшСумму(СекретныйКод);
	КонецЕсли;;
	
	ПустойБлок = ПолучитьДвоичныеДанныеИзСтроки("");
		
	ПерваяЧасть = ЗаполнитьБлокКонстантой(СекретныйКод, РазмерБлока, "0x00");
	ВтораяЧасть = ЗаполнитьБлокКонстантой(ПустойБлок, РазмерБлока, "0x36");
	ТретьяЧасть = ПрименитьБинарноеПобитовоеИсключающееИЛИ(ПерваяЧасть, ВтораяЧасть);
	ЧетвертаяЧасть = ЗаполнитьБлокКонстантой(ПустойБлок, РазмерБлока, "0x5C");
	ПятаяЧасть = ПрименитьБинарноеПобитовоеИсключающееИЛИ(ПерваяЧасть, ЧетвертаяЧасть);
		
	СклеиваемыеДанные = Новый Массив();
	СклеиваемыеДанные.Добавить(ТретьяЧасть);
	СклеиваемыеДанные.Добавить(Сообщение);
	
	ШестаяЧасть = СоединитьДвоичныеДанные(СклеиваемыеДанные);
	
	СклеиваемыеДанные = Новый Массив();
	СклеиваемыеДанные.Добавить(ПятаяЧасть);
	СклеиваемыеДанные.Добавить(ПолучитьХэшСумму(ШестаяЧасть));	
	
	СедьмаяЧасть = СоединитьДвоичныеДанные(СклеиваемыеДанные);
		
	Возврат ПолучитьХэшСумму(СедьмаяЧасть);	КонецФункции

Функция ПолучитьХэшСумму(Знач Данные) 
	
	ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.SHA256);
	ХешированиеДанных.Добавить(Данные);
	
	Возврат ХешированиеДанных.ХешСумма;
	
КонецФункции

Функция ЗаполнитьБлокКонстантой(Знач ИсходныеДанные, Знач РазмерБлока, Знач hexКонстанта)
		
	ЧтениеДанных = Новый ЧтениеДанных(ИсходныеДанные);
	Буфер = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеДанных.Закрыть();
	
	ПотокВПамяти = Новый ПотокВПамяти();
	ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти);	
	Если Буфер.Размер > 0 Тогда
		ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(Буфер);
	КонецЕсли;	
	//Заполним константой до конца блока
	decКонстанта = ЧислоИзШестнадцатеричнойСтроки(hexКонстанта);
	Для Итерация = Буфер.Размер + 1 По РазмерБлока Цикл
		ЗаписьДанных.ЗаписатьБайт(decКонстанта);
	КонецЦикла;
	ЗаписьДанных.Закрыть();
	
	Возврат ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();
	
КонецФункции

Функция ПрименитьБинарноеПобитовоеИсключающееИЛИ(Знач ПерваяЧастьДанных, Знач ВтораяЧастьДанных)
	
	ЧтениеДанных = Новый ЧтениеДанных(ПерваяЧастьДанных);		
	ПервыйБуфер = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеДанных.Закрыть();
	
	ЧтениеДанных = Новый ЧтениеДанных(ВтораяЧастьДанных);	
	ВторойБуфер = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеДанных.Закрыть();
			
	ПотокВПамяти = Новый ПотокВПамяти();
	ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти);	
	
	Если ПервыйБуфер.Размер > ВторойБуфер.Размер Тогда
		ПервыйБуфер.ЗаписатьПобитовоеИсключительноеИли(0, ВторойБуфер, ВторойБуфер.Размер);
		ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ПервыйБуфер);
	Иначе 
		ВторойБуфер.ЗаписатьПобитовоеИсключительноеИли(0, ПервыйБуфер, ПервыйБуфер.Размер);
		ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ВторойБуфер);
	КонецЕсли;
	
	ЗаписьДанных.Закрыть();
	
	Возврат ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();

КонецФункции 

ПотокВПамятиСекретныйКод = Новый ПотокВПамяти;
ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамятиСекретныйКод);
ЗаписьДанных.ЗаписатьСимволы("СекретныйКод", КодировкаТекста.UTF8);
	
ПотокВПамятиСообщение = Новый ПотокВПамяти;
ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамятиСообщение);
ЗаписьДанных.ЗаписатьСимволы("Сообщение", КодировкаТекста.UTF8);
	
Подпись = HMAC256(ПотокВПамятиСекретныйКод.ЗакрытьИПолучитьДвоичныеДанные(), ПотокВПамятиСообщение.ЗакрытьИПолучитьДвоичныеДанные())

 

 
0
Еще от автора
≡ к списку статей