Что такое HMAC и JWT и как это использовать в 1С

28.01.19

Интеграция - Внешние источники данных

Лёгкая статья про стандарты HMAC и JWT с небольшой теорией и исходным кодом.

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

Наименование Файл Версия Размер
Конфигурация содержащая код для работы с HMAC и JWT
.cf 22,45Kb
215
.cf 1.2 22,45Kb 215 Скачать

Лёгкая статья про стандарты HMAC и JWT с небольшой теорией и исходным кодом.

Коллеги, позвольте вам рассказать о вещах, которые далеки от обычной разработки в 1С.

Вероятно, что сейчас у вас нет необходимости использовать HMAC и JWT, но время не стоит на месте, и, возможно, в очередном проекте интеграции вы задействуете описываемые ниже стандарты.

Часть первая, теоретическая.

HMAC (Hash-based message authentication code) - это хэш, который вычисляется, основываясь на двух значениях: 'ключ' и 'сообщение'. Такой хэш нужен, чтобы гарантировать, что данные, передаваемые в ненадежной среде, не были изменены посторонними лицами.

Зачем же нам использовать HMAC, когда у нас есть, например, HTTPS?

HMAC полезен, когда участников в обмене сообщениями больше, чем два.

Например, у нас есть три участника:

  •  'Провайдер API' - сторонний сервис, который принимает запросы на отправку открыток и букетов
  •  'Сервер' - серверная часть вашего приложения
  •  'Клиент' - клиентская часть, с которой работают пользователи

'Провайдер API' предоставляет две вещи для выполнения запросов – это AccounID и SecretKey. 'Провайдер API' ни чего не знает про ваших пользователей, чтобы принять запрос на отправку открытки, ему нужно удостовериться, что просящий знает AccounID и SecretKey.

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

Разумеется, очевидное решение задачи заключается в том, чтобы все клиентские запросы направить через 'Сервер':

  1.  'Клиент' - формирует запрос на отправку открытки для 'Сервера';
  2.  'Сервер' - проверяет права конкретного пользователя и если всё хорошо, то перенаправляет вызов на 'Провайдера API';
  3.  'Провайдер API' делает необходимые действия;
  4. Далее по цепочке обратно передается результат вызова.

Но что, если у нас клиенты генерируют десятки тысяч таких запросов, и не хотят долго ждать результат выполнения? Или наши запросы содержат потоковое аудио (для музыкальных открыток), которым не хотелось бы грузить 'Сервер'? Более того, а что, если 'Клиент' передает конфиденциальные сведения, которые и вовсе не должны попасть на 'Сервер' (букет с интимным посланием)?
Почему бы нам сразу не слать запросы с 'Клиента' на 'Провайдер API'?

Тогда нам придется 'Клиенту' сообщить AccounID и SecretKey, которые нужны 'Провайдеру API'. Но поскольку у нас разные клиенты имеют разные права (открытки, букеты) и в какой то момент у клиента права могут быть и вовсе отозваны, то мы не можем сообщать 'Клиенту' AccounID и SecretKey.
В этот момент нам и пригодится HMAC.
Благодаря HMAC мы можем построить работу следующим образом:

  1. 'Клиент' запрашивает у 'Сервера' специальный Token
  2. 'Сервер' делает Token с помощью HMAC, учитывая права пользователя и ограничивая действие токена по времени:
Token = HMAC(SecretKey, AccounID + ПравоПользователя + ДатаВремяДоступа)

Теперь пользователь может обратиться напрямую к 'Провайдеру API' за конкретной услугой и предоставить Token, AccounID и ДатаВремяДоступа. 'Провайдер API' вычисляет Token и сверяет его с тем, что прислал 'Клиент' и той услугой которую 'Клиент' хочет получить.

В данной схеме 'Клиент' является той самой ненадежной средой. Фактически запрос должен делать 'Сервер', потому что 'Провайдер API' сказал свой SecretKey только 'Серверу'. Но наш 'Сервер' не хочет делать запросы и разрешает на время 'Клиенту' самостоятельно делать запросы. Наш 'Сервер' не доверяет 'Клиенту' и использует HMAC, чтобы обеспечить неизменность выданных разрешений на использование услуг 'Провайдера API'.


Часть вторая, считаем HMAC.

Давайте посмотрим под капот и узнаем, что же внутри функции HMAC.

Функция HMAC на вход принимает SecretKey и Message типа ДвоичныеДанные и вид хэш функции.

Function HMAC(Val SecretKey, Val Message, Val HashFunc) Export

	BlSz = 64;
	
	// Если ключ больще чем размер блока, то в качестве ключа используем хэш от ключа
	If SecretKey.Size() > BlSz Then
		SecretKey = Hash(SecretKey, HashFunc);
	EndIf;
	
	EmptyBin = GetBinaryDataFromString("");
	SecretKey = BinLeft(SecretKey, BlSz);
	
	// Если ключ меньше блока, то добиваем его нулями до размера блока
	К0 = BinRightPad(SecretKey, BlSz, "0x00");
	
	// Делаем k_ipad, выполняем операцию «побитовое исключающее ИЛИ» ключа c константой 0x36
	ipad = BinRightPad(EmptyBin, BlSz, "0x36");
	k_ipad = BinBitwiseXOR(К0, ipad);
	
	// Делаем k_opad, выполняем операцию «побитовое исключающее ИЛИ» ключа c константой 0x5c
	opad = BinRightPad(EmptyBin, BlSz, "0x5C");
	k_opad = BinBitwiseXOR(К0, opad);
	
	// склеиваем k_ipad и сообщение
	k_ipad_Message = BinConcat(k_ipad, Message);
	
	// вычисляем хэши и получаем результат
	k_opad_Hash = BinConcat(k_opad, Hash(k_ipad_Message, HashFunc));
	res = Hash(k_opad_Hash, HashFunc);
	
	Return res;

EndFunction

Функции BinLeft, BinRightPad, BinBitwiseXOR и BinConcat реализованы с использованием возможностей платформы, которые появились в версии 8.3.10.2168.

Теперь мы можем делать хэш и комбинировать данные для подписи любым способом.

Например, так:

Token = HMAC(SecretKey, AccounID + ПравоПользователя + УникальныйИдентификатор + "допДанные7" + ДатаВремяДоступа + ИмяПользователя)

Такая свобода действий может породить хаос и как следствие – увеличение сроков разработки и интеграции. Что, если бы у нас был стандарт, по которому определен формат для сообщений?

Такой стандарт у нас есть, и называется он JWT.


Часть третья, пару слов про JWT

JWT (JSON Web Token) – это стандарт, по которому определено, в каком виде будет выглядеть токен для клиента. По сути JWT это строка, состоящая из трех частей соединенных точками: заголовок, данные и подпись.

Например: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Этот токен содержит:

заголовок (Header)

{
  "alg": "HS256",
  "typ": "JWT"
}

данные (Payload)

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

и подпись (Signature):

TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Польза от JWT в том, что это стандарт и для этого стандарта уже готовы библиотеки на всевозможных платформах.

К этой статье приложена реализация JWT на чистом 1C:Enterprise 8.3.10.2168.


Например, вы делаете интеграцию со сторонним сервисом, и вам необходимо договорится об авторизации запросов от пользователей. С большой вероятностью сторонний сервис реализован на платформе, для которой есть готовая библиотека JWT. Вы как прогрессивный разработчик 1С теперь можете предложить использовать стандарт RFC 7519 – т.е. JWT. Каждый со своей стороны возьмет готовую библиотеку и вуаля – пользователи ходят напрямую в сторонний сервис.

 

Заключение

Благодарю, что прочитали эту статью. Надеюсь, вы нашли для себя полезное.

Пожалуйста, напишите в комментариях, как по вашему мнению можно было бы использовать JWT в мире 1С уже сейчас.

Любые, возможно бредовые, идеи принимаются. Например: отправка whatsapp-сообщений прямо из тонкого клиента.

HMAC JWT Twilio DocumentDB

См. также

Перенос данных из Парус 10 в ЗГУ ред.3

Внешние источники данных Кадровый учет Файловый обмен (TXT, XML, DBF), FTP Обмен между базами 1C Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактических удержаниях, НДФЛ, вычетах, страховых взносах из базы Парус 10 учреждений в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ) и начать с ней работать с любого месяца года.

60000 руб.

05.10.2022    9156    9    8    

10

Перенос данных из Парус 8 в ЗГУ 3

Зарплата Внешние источники данных Бюджетный учет Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактических удержаниях, НДФЛ, вычетах, страховых взносах из базы Парус 8 учреждений в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ) и начать с ней работать с любого месяца года.

84000 руб.

19.08.2020    22351    18    1    

21

Автоматическая многопоточная выгрузка данных 1С 8.3 в БД Clickhouse и MS SQL (для работы с данными 1С в BI-системах)

Внешние источники данных Платформа 1С v8.3 Управляемые формы Анализ и прогнозирование Конфигурации 1cv8 Узбекистан Беларусь Кыргызстан Молдова Россия Казахстан Платные (руб)

Готовое решение для автоматизированной выгрузки данных из 1С 8.3, а также MS Excel в базу данных ClickHouse, а также в Microsoft SQL для работы с данными 1С в Yandex Datalens, Visiology, Apache Superset (и не только) - "Экстрактор данных 1С в BI". Решение отлично работает со всеми типовыми (и не только) конфигурациями 1С 8.3 для управляемых форм. Gозволяет автоматизировать работу бизнес-аналитика по ежедневной выгрузке данных из 1С в БД ClickHouse для последующей работы с этой БД в Yandex Datalens/ Система полностью автоматизирует работу с хранилищем данных в БД Clickhouse/MS SQL. Не надо быть программистом, чтобы одной кнопкой получать любые данные из 1С в Вашей BI-системе

230000 руб.

15.11.2022    12913    12    47    

28

Перенос данных из Парус 7.хх в ЗГУ ред.3

Внешние источники данных Зарплата Бюджетный учет Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактических удержаниях, НДФЛ, вычетах, страховых взносах из базы Парус 7.хх учреждений в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ) и начать с ней работать с любого месяца года.

24000 руб.

24.04.2017    48630    96    159    

86

Перенос начальных остатков из Парус 7.71 в БГУ

Внешние источники данных Взаиморасчеты Учет ОС и НМА Логистика, склад и ТМЦ Бюджетный учет Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 2.0 1С:Бухгалтерия государственного учреждения Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Перенос словарей и начальных остатков из ПП Парус-Бухгалтерия Бюджет 7.71 в 1Сv8 БГУ2. Заполнение словарей и документов по вводу начальных остатков. Не требуется установка ПП Парус7. Возможна дозагрузка. Позволит автоматически и наиболее полно ввести данные в программу для начала работы. 

15600 руб.

08.12.2011    81472    128    123    

146

Перенос данных из Парус 10 (Торнадо) в ЗГУ ред.3 через Excel

Внешние источники данных Загрузка и выгрузка в Excel Зарплата Бюджетный учет Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате из Парус 10(Торнадо) учреждений через файлы Excel в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ). В принципе, обработка может быть использована для загрузки из файлов Excel, полученных из любых информационных систем.

24000 руб.

16.11.2018    29980    20    31    

21
Отзывы
1. davdykin 25 21.04.17 21:42 Сейчас в теме
Спасибо за информацию, учитывая популярность микросервисов думаю может вполне пригодиться.
sandr13; Shmell; o.nikolaev; usalteam; stilet; ponkratov; pintov; DrAku1a; +8 Ответить
Остальные комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. davdykin 25 21.04.17 21:42 Сейчас в теме
Спасибо за информацию, учитывая популярность микросервисов думаю может вполне пригодиться.
sandr13; Shmell; o.nikolaev; usalteam; stilet; ponkratov; pintov; DrAku1a; +8 Ответить
2. stas1976 14 26.04.17 11:23 Сейчас в теме
3. NcSteel 04.05.17 20:58 Сейчас в теме
Подскажите, пожалуйста, вариацию если в качестве соли используется не строковый ключ, а сертификат
4. user757186 29.06.17 19:49 Сейчас в теме
(3) функции хэширования и подписи работают с двоичными данными, строки - это лишь частный случай двоичных данных. Если вы посмотрите внимательно код - там нет фукнкций работы со строками, там используются функции работы с двоичными данными.
5. pbazeliuk 1954 17.10.17 10:19 Сейчас в теме
Для MD5 и SHA-1 у вас не верный размер блока, он должен быть 64. Можете проверить в любом онлайн генераторе.
7. pintov 131 18.10.17 10:51 Сейчас в теме
(5)
да, вы правы, спасибо.
6. pbazeliuk 1954 17.10.17 11:36 Сейчас в теме
И последнее, если ключ больше размера блока, его необходимо предварительно хешировать
8. pintov 131 26.10.17 18:11 Сейчас в теме
(6) Обновил код по вашим замечаниям. Благодарю, что нашли ошибки.
9. moro_as 17.02.18 06:31 Сейчас в теме
задача в интеграции с https://docs.veeroute.com/api/examples/json_examples/
есть что-то общее между JWT?
застрял на функции getBytes() какой аналог в 1с (двоичные данные?)
направьте куда копать.
10. pintov 131 18.02.18 09:52 Сейчас в теме
(9) да
в строчке
byte[] passBytes = password.getBytes();

по всей видимости следует использовать глобальный метод ПолучитьДвоичныеДанныеИзСтроки (GetBinaryDataFromString)

Затем вам нужно будет конвертировать массив в двоичные данные
byte[] saltBytes = listToArray(ticket.getSalt());

Для этого вам понадобится объект ЗаписьДанных (DataWriter)
и метод ЗаписатьБайт (WriteByte)

Далее нужно будет соеденить passBytes, saltBytes и вычислить хэш
byte[] PaS = makeBytesHash(concatenateByteArrays(passBytes, saltBytes), "SHA-512");


Для соединения passBytes, saltBytes используйте функцию из статьи
Function BinConcat(Val BinaryData1, Val BinaryData2)


А вот с хэшем беда.
В 1С есть только хэш-функции
CRC32
MD5
SHA1
SHA256

Поэтому ищем в интернете варианты. Например в этой статье есть два подхода для получения SHA-512:
https://infostart.ru/public/175332/

Осталось только полученный хэш конвертировать в массив - для этого используйте объект ЧтениеДанных (DataReader).
11. moro_as 19.02.18 11:29 Сейчас в теме
(10) Спасибо огромное!!!
Затем вам нужно будет конвертировать массив в двоичные данные
byte[] saltBytes = listToArray(ticket.getSalt());

Для этого вам понадобится объект ЗаписьДанных (DataWriter)
и метод ЗаписатьБайт (WriteByte)


Функция listToArray(Знач Массив) Экспорт
	Перем Результат;
	ПотокВПамяти = Новый ПотокВПамяти();
	ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти);	
	Для Каждого Элемент из Массив Цикл
		ЗаписьДанных.ЗаписатьБайт(Число(Элемент));
	КонецЦикла;
	Результат = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();
	Возврат Результат;
КонецФункции
Показать


ЗаписатьБайт выдаёт ошибку:
по причине:
Значение байта должно быть в диапазоне от 0 до 255,
а в передаваемом массиве [-100,-96,20,51,89,-47,-80,-128,86,43,-24,124,-109,12,47] есть элементы с минусовым значением...
12. moro_as 19.02.18 13:29 Сейчас в теме
(11) Оказывается байт java (-127...128), вот и вся ошибка.
13. moro_as 19.02.18 19:11 Сейчас в теме
(10)
Для соединения passBytes, saltBytes используйте функцию из статьи
Function BinConcat(Val BinaryData1, Val BinaryData2)

штатным образом можно получить через СоединитьДвоичныеДанные
14. moro_as 19.02.18 23:10 Сейчас в теме
(10)
А вот с хэшем беда.
В 1С есть только хэш-функции
CRC32
MD5
SHA1
SHA256

Поэтому ищем в интернете варианты. Например в этой статье есть два подхода для получения SHA-512:
https://infostart.ru/public/175332/


Да, действительно беда.
Но можно и вот так попробовать:

Функция CryptoSHA512(Строка) Экспорт 
	Текст = Новый COMОбъект("System.Text.UTF8Encoding");
	КриптоSHA512 = Новый COMОбъект("System.Security.Cryptography.SHA512Managed");
	Байты = Текст.GetBytes_4(Строка); 
	МассивХэш = КриптоSHA512.ComputeHash_2(Байты).Выгрузить();
	Возврат МассивХэш;
КонецФункции
Показать
15. Varsaavius 18.05.18 12:28 Сейчас в теме
При использовании алгоритма RS256, при декодировании постоянно не совпадают сигнатуры. /:
16. pallid 270 16.01.19 10:34 Сейчас в теме
Подскажите есть ли замена платформенного метода Buffer1.WriteBitwiseXor(0, Buffer2, Buffer2.Size) на аналог
Function BinBitwiseXOR(Val BinaryData1, Val BinaryData2)
	
	MemoryStream = New MemoryStream();
	DataWriter = New DataWriter(MemoryStream);
	
	DataReader1 = New DataReader(BinaryData1);
	DataReader2 = New DataReader(BinaryData2);
	
	Buffer1 = DataReader1.ReadIntoBinaryDataBuffer();
	Buffer2 = DataReader2.ReadIntoBinaryDataBuffer();
	
	If Buffer1.Size > Buffer2.Size Then
		Buffer1.WriteBitwiseXor(0, Buffer2, Buffer2.Size);
		DataWriter.WriteBinaryDataBuffer(Buffer1);
	Else 
		Buffer2.WriteBitwiseXor(0, Buffer1, Buffer1.Size);
		DataWriter.WriteBinaryDataBuffer(Buffer2);
	EndIf;
	
	res = MemoryStream.CloseAndGetBinaryData();
	Return res;

EndFunction

Показать
17. pintov 131 25.01.19 10:48 Сейчас в теме
(16) К сожалению, у меня нет готового кода, которы бы заменял метод WriteBitwiseXor
18. frkbvfnjh 785 28.01.19 15:21 Сейчас в теме
Выдает ошибку:
Процедура или функция с указанным именем не определена (ValueIsNotFilled)
21. pintov 131 28.01.19 16:42 Сейчас в теме
(18)
Пожалуйста добавьте метод
Function ValueIsNotFilled(Value) Export

	Return Not ValueIsFilled(Value);

EndFunction
19. frkbvfnjh 785 28.01.19 15:33 Сейчас в теме
Блин капец:
Обработка.HMAC_JWT.Форма.Form.Форма Возможно ошибочный метод: "DecodeHS256"
Обработка.HMAC_JWT.Форма.Form.Форма Возможно ошибочный метод: "DecodeRS256"
Обработка.HMAC_JWT.Форма.Form.Форма Возможно ошибочный метод: "EncodeHS256"
Обработка.HMAC_JWT.Форма.Form.Форма Возможно ошибочный метод: "EncodeRS256"
Нет таких функций!
Вы бы перепроверили все. И раз уж на то пошло, то выкладывали бы сразу все в виде одного файла демонстрационной конфигурации или все функции в обработку засунули, а не кучу разрозненных файлов
22. pintov 131 28.01.19 17:13 Сейчас в теме
(19) код скаченных модулей Cryptography и JWT рабочий.
Демонстрационная обработка использует интерфейс от несколько обновленного модуля JWT.
В связи с этим обновил публикацию - залил последнюю версию модуля JWT.
Прошу прощения за неудобства.

Вышлю вам последнюю версию в ЛС.
26. frkbvfnjh 785 29.01.19 14:17 Сейчас в теме
(22) Спасибо большое! Теперь все работает.
20. frkbvfnjh 785 28.01.19 15:36 Сейчас в теме
Я так понимаю есть только Encode и Decode и кодирование производится только по алгоритму SHA256. Все верно?
23. pintov 131 28.01.19 17:22 Сейчас в теме
(20) средствами 1С реализован только алгоритм HS256. Для алгоритма RS256 я использовал COM-объект из сторонней библиотеки.
24. frkbvfnjh 785 29.01.19 05:59 Сейчас в теме
(23) Хорошо, но из обработки идет вызов функций которых нет в общих модулях, это сбивает с толку. Тогда переименовали бы в общем модуле функции в функции с префиксом HS256, а для RS256 сделали бы "заглушку" с комментариями. Или переименуйте вызываемые функции в самой обработке, удалите те, которых нет на самом деле. Да и было бы отлично, если привести готовый код для RS256 который вы использовали при работе со сторонней библиотекой, я думаю никто бы не огорчился, а только благодарны были бы. А то начинаешь сомневаться в том правильно ли все понял, отнимает время что бы разобраться что к чему и как правильно пользоваться.
NikiforovVA; +1 Ответить
38. mcOrk 23.10.19 11:47 Сейчас в теме
А можно получить данную библиотеку? Не получилось найти на просторах интернета. Спасибо.
39. pintov 131 23.10.19 13:13 Сейчас в теме
(38) Да, конечно. В конце статьи есть кнопка "Скачать". Используйте, пожалуйста, её.
40. mcOrk 23.10.19 16:17 Сейчас в теме
(39) CF скачал, но я имел ввиду про стороннюю библиотеку, используемую Вами "AddIn.RSAUtils" Отдельной ссылки нигде не нашел.
41. pintov 131 23.10.19 17:38 Сейчас в теме
(40) по поводу AddIn.RSAUtils - напишите, мне пожалуйста на почту vasily@pintov.ru
42. donyab 9 17.12.19 12:59 Сейчас в теме
(40)
(41)
Аналогичная ситуация, я так понимаю это что то самописное, может его приложить в пример к статье?
Первое что выдает гугл при поиске RSAUtils - это вирус шифровальщик)
51. NikiforovVA 12 05.10.21 17:48 Сейчас в теме
(23)
Где её взять, очень нужна?
25. frkbvfnjh 785 29.01.19 06:19 Сейчас в теме
В целом публикация хорошая. Написанная Вами библиотека функций очень нужная!
27. frkbvfnjh 785 29.01.19 14:18 Сейчас в теме
Все работает! Спасибо!
28. kloze 14.05.19 11:22 Сейчас в теме
Подскажите почему не работает. Сейчас HMAC получаю так

<?php 
$p_sign = hash_hmac('sha1', '811576.003RUB8290666011119https://www.test.ru2014052019110700003430', pack('H*', '3716699F804BE05E9E8D767ACEB6B88E')); 
echo $p_sign  
?>


HMAC = 7a619c6b8f79b95fc359a990075d6aeb2f6a6965

А через эту обработку получает 9E83F1A022F0F916580132CA54639DA576E573BC
29. pintov 131 14.05.19 11:55 Сейчас в теме
30. malikov_pro 1288 04.10.19 20:31 Сейчас в теме
А можете ли Вы (автор) сделать реализацию pbkdf2? Тема Вам близка а реализации под 1C не нашел.
31. pintov 131 07.10.19 11:00 Сейчас в теме
(30) Я бы с удовольствием. К сожалению, не понимаю для каких практических задач нужен pbkdf2 в 1С. Например HMAC нужен был для интеграции с Twilio. И чтобы избавится от обращения к COM-объекту был реализован JWT и HMAC средствами платформы.
Для каких реальных задач вы видите необходимость в реализации pbkdf2?
32. malikov_pro 1288 07.10.19 11:57 Сейчас в теме
(31)
1. Передача данных для проверки PIN кодов в удаленной системе (сейчас партнер передает Base64 строку с хешем солью и параметрами, из за отсутствия реализации проверяем через его API, сначала планировалось локально).
2. Хранение паролей для внешних пользователей, куча решений когда внешних пользователей хранят как обычных. Я в решениях хранил в отдельном справочнике и по простому хешировал пароль.
33. pintov 131 07.10.19 15:59 Сейчас в теме
(32) По второму кейсу в простого хэша может быть и достаточно.
По первому кейсу конечно нужна реализация pbkdf2.
Не могу обещать, что сделаю в скором времени.
Если руки дойдут – оповещу Вас.
34. maxx 991 14.10.19 09:13 Сейчас в теме
Добрый день! По поводу использования такого стандарта 1С. Если вот такой пример. Пусть надуманный, но недалеко от реального использования.

Есть торговая сеть, состоящая из независимых организаций какого-нибудь торгового бренда, сети. Организации независимые (разные юридическое лица) и имеют свои базу 1С пусть "1С:Управление торговлей", но доработки у каждого свои , учитывающие своим местные особенности, свои программисты.

Так как организации представляют один брэнд, они хотят при отсутствии товару у себя, посмотреть у своих коллег в других регионах. Так как единой общей базы нет, то решили сделать следующее: пользователи баз 1С могут зайти в личный веб-кабинет и там увидеть остатки других организаций в других регионах. Для этого используется технология http-запросов или soap-запросов, при этом конечно в самих базах 1С заведены пользователи только "свои", не чужих регионов.

В своей родной "базе" 1С реализован механизм выдаче токена пользователю для веб-кабинета c правами на просмотр разной информации. Между базами 1С произведен обмен SecretKey. В каждой базе 1С реализовали веб-сервис, который получает Token и уже разобрав токен, понимается какие права данного пользователя, время токена и т.п.

Возможно, такое использование?
35. pintov 131 14.10.19 11:06 Сейчас в теме
(34) Да, отличный пример!

Благодаря JWT нет необходимости всем участникам сети делать в своих базах внешних пользователей.

Я вижу процесс так:
Участник сети выдает веб-кабинету свой SecretKey.
Веб-кабинет с помощью SecretKey делает токен.
Другой участник сети с помощью токена может сходить в базу первого участника сети за остатками.
Первый участник сети по токену и SecretKey может определить выполнять запрос или нет.
Токен не дает перманентный доступ - у него есть срок годности.

Чтобы такую систему запустить нужно всем добавить в свои базы функционал:
1. Генерация SecretKey и отправка его в Веб-кабинет
2. HTTP-сервис, который умеет проверять токены и отдавать остатки
Это можно реализовать через расширение.
Ещё нужно сделать веб-кабинет, который фактически может не иметь веб-интерфейса. Достаточно сделать HTTP-сервис, который умеет принимать SecretKey и выдавать токены.
36. maxx 991 14.10.19 11:28 Сейчас в теме
(35) Один момент, который хотелось бы уточнить, нужно ли передавать веб-кабинету SecretKey, почему SecretKey нельзя передавать между базами 1С просто и там хранить?.

А если веб-кабинет, сделан на чистом js (есть фрейворки сейчас даже таки) с запросами ajax, т.е. весь веб-часть это клиентская часть (т.е. там хранить SecretKey не надо)?

Т.е. выдача токена в базе 1С с помощью SecretKey "базы 1", а в другой базе 1С "базы 2" проверка этого токена с помощью SecretKey, т.е. база1 обменялось с базой2 SecretKey (конечно, если SecretKey по-хорошему для каждой базы 1С надо делать свой, чтобы в случае проблем можно было быстро поменять SecretKey и ранее выданные токены перестали работать).
37. pintov 131 14.10.19 12:51 Сейчас в теме
(36) Можно так сделать как вы описываете, но тогда JWT теряет свой смысл, потому что все смогут бесконтрольно делать токены.
Если токены выдавать централизовано, то можно ограничить количество токенов, чтобы пользователи не злоупотребляли возможностью видеть остатки у других пользователей.
В токене ведь кроме срока его действия можно хоть конкретный код номенклатуры указать.
43. leemuar 20.01.20 12:24 Сейчас в теме
Большое спасибо за код!

Очень жаль что ваша статья не находится первой в результате поисковиков по запросу "hmac для 1с", там костыли для старых версий платформы
44. sisdrou 23 30.01.20 09:38 Сейчас в теме
При формировании JWT, кодирует символ "\" перед каждым параметром в JSON. Как от этого избавиться ?
45. slaviksoft 74 16.04.20 12:22 Сейчас в теме
Есть проблема при декодировании (возможно и кодировании)
Парсинг JSON в структуру не подходит
Такие ключи как "user-agent" невозможно в структуру поместить
Очевидно тут больше подошло бы соответствие.
46. slaviksoft 74 16.04.20 12:23 Сейчас в теме
Недопустимое имя свойства: 'user-agent' для чтения JSON в объект Структура
{CommonModule.JWT.Module(228)}: Return ReadJSON(JSONReader, False);
{CommonModule.JWT.Module(152)}: payloadData = ParseJSON(payloadJson);
{DataProcessor.HMAC_JWT.Form.Form.Form(44)}: Payload = JWT.DecodeHS256(JWT_Value, JWT_Key);
{DataProcessor.HMAC_JWT.Form.Form.Form(63)}: JWT_DecodeAtServer();

по причине:
Недопустимое имя свойства: 'user-agent' для чтения JSON в объект Структура
47. anton.fly7 173 28.04.20 13:32 Сейчас в теме
Случайно не подскажете как зашифровать JWT алгоритмом ES256 ?
в питоне это выглядит так jws.sign(claims, secret2, algorithm=ALGORITHMS.ES256)
48. Xershi 1473 19.10.20 16:00 Сейчас в теме
В типовых модуль "РаботаВМоделиСервисаБТС":

#Область Криптография

Функция HMACSHA256(Знач Ключ, Знач Данные)
	
	Возврат HMAC(Ключ, Данные, ХешФункция.SHA256, 64);
	
КонецФункции

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

Функция HMAC(Знач Ключ, Знач Данные, Тип, РазмерБлока)
	
	Если Ключ.Размер() > РазмерБлока Тогда
		Ключ = Хеш(Ключ, Тип);
	КонецЕсли;
	
	Если Ключ.Размер() < РазмерБлока Тогда
		Ключ = ПолучитьHexСтрокуИзДвоичныхДанных(Ключ);
		Ключ = Лев(Ключ + ПовторитьСтроку("00", РазмерБлока), РазмерБлока * 2);
	КонецЕсли;
	
	Ключ = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзHexСтроки(Ключ));
	
	ipad = ПолучитьБуферДвоичныхДанныхИзHexСтроки(ПовторитьСтроку("36", РазмерБлока));
	opad = ПолучитьБуферДвоичныхДанныхИзHexСтроки(ПовторитьСтроку("5c", РазмерБлока));
	
	ipad.ЗаписатьПобитовоеИсключительноеИли(0, Ключ);
	ikeypad = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(ipad);
	
	opad.ЗаписатьПобитовоеИсключительноеИли(0, Ключ);
	okeypad = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(opad);
	
	Возврат Хеш(СклеитьДвоичныеДанные(okeypad, Хеш(СклеитьДвоичныеДанные(ikeypad, Данные), Тип)), Тип);
	
КонецФункции

Функция СклеитьДвоичныеДанные(ДвоичныеДанные1, ДвоичныеДанные2)
	
	МассивДвоичныхДанных = Новый Массив;
	МассивДвоичныхДанных.Добавить(ДвоичныеДанные1);
	МассивДвоичныхДанных.Добавить(ДвоичныеДанные2);
	
	Возврат СоединитьДвоичныеДанные(МассивДвоичныхДанных);
	
КонецФункции

Функция ПовторитьСтроку(Строка, Количество)
	
	Части = Новый Массив(Количество);
	Для к = 1 По Количество Цикл
		Части.Добавить(Строка);
	КонецЦикла;
	
	Возврат СтрСоединить(Части, "");
	
КонецФункции

#КонецОбласти
Показать
silberRus; dctvghbdtn; pintov; +3 Ответить
49. dctvghbdtn 28.07.21 11:31 Сейчас в теме
(48) Кто нибудь делал замеры быстродействия предложенного варианта и реализации в типовом решении Фирмы 1С?
50. NikiforovVA 12 05.10.21 17:00 Сейчас в теме
Добрый день, где взять библиотеку RSAUtils???
user1232941; 1spectr; +2 Ответить
52. fieryfist 15 14.01.22 23:04 Сейчас в теме
Спасибо за статью, а можно как-то сформировать подпись без использования сторонней библиотеки RSAUtils ?
53. fieryfist 15 18.01.22 14:31 Сейчас в теме
(52) нашел вариант без этой библиотеки в публикации
KAV2; pintov; +2 Ответить
54. Aspire1C 862 16.03.22 16:08 Сейчас в теме
Есть какие то новые примеры в связи с платформенным решением по JWT?
https://wonderland.v8.1c.ru/blog/autentifikatsiya-s-pomoshchyu-jwt-tokenov/
vano-ekt; SpartakM; +2 Ответить
55. Dipod 111 24.01.23 20:15 Сейчас в теме
Спасибо за алгоритм декодирования JWT. Странно, что 1С-ники добавили объект ТокенДоступа в платформе 8.3.21, сделали преобразование этого токена в строку, а вот обратное декодирование не сделали.
56. pintov 131 11.03.23 12:34 Сейчас в теме
57. KAV2 156 06.05.23 08:06 Сейчас в теме
Возникла задача сгенерировать JWT для работы с Google API (через Google IAM Service Account), там используется алгоритм RSA256, и не полчилось использовать эту библиотеку и также появившийся в платформе 8.3.21 ТокенДоступа (возможно что-то не правильно сделал). Пришлось написать внешнюю программу, чтобы уже из 1С вызывать её и генерировать JWT.
Оставьте свое сообщение