|
Помогите найти рабочий пример реализации HMACSHA256 в 1С:8.2 | ☑ | ||
---|---|---|---|---|
0
Puzoter
13.04.18
✎
11:29
|
Задача - сделать запрос к сайту с использованием ХЭШа HMACSHA256.
Те примеры, которые я нашел почему-то возвращают результат, отличный от функции hash_hmac() PHP. |
|||
1
oleg_km
13.04.18
✎
13:32
|
||||
2
Puzoter
13.04.18
✎
14:31
|
В hash_hmac() PHP используется два параметра - данные и секретный ключ, а в ХешированиеДанных() в 8.3 можно использовать ключ?
|
|||
3
Puzoter
13.04.18
✎
14:32
|
(1) Это сложно слишком. Проще наверно поднять ПХП и делать к нему ГЕТ запрос.
|
|||
4
Puzoter
13.04.18
✎
15:00
|
Для получения ХЭШа использую функцию:
Функция ЗашифроватьSHA256(Строка, СекретныйКлюч) Соотв16 = Новый Соответствие; Соотв16.Вставить(0 , "0"); Соотв16.Вставить(1 , "1"); Соотв16.Вставить(2 , "2"); Соотв16.Вставить(3 , "3"); Соотв16.Вставить(4 , "4"); Соотв16.Вставить(5 , "5"); Соотв16.Вставить(6 , "6"); Соотв16.Вставить(7 , "7"); Соотв16.Вставить(8 , "8"); Соотв16.Вставить(9 , "9"); Соотв16.Вставить(10, "a"); Соотв16.Вставить(11, "b"); Соотв16.Вставить(12, "c"); Соотв16.Вставить(13, "d"); Соотв16.Вставить(14, "e"); Соотв16.Вставить(15, "f"); Текст = Новый COMОбъект("System.Text.UTF8Encoding"); //Текст = Новый COMОбъект("System.Text.ASCIIEncoding"); Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA256"); Криптография.Key = Текст.GetBytes_4(СекретныйКлюч); ХешБайт = Криптография.ComputeHash_2(Текст.GetBytes_4(Строка)).Выгрузить(); Хеш = ""; Для Каждого Байт Из ХешБайт Цикл Чс = Цел(Байт/16); Хеш = Хеш + Прав("0" + Соотв16.Получить(Чс) + Соотв16.Получить(Байт-Чс*16), 2); КонецЦикла; Возврат Хеш; КонецФункции Функция возвращает строку типа: 41c9dd976bcfd8be539f40c0e250d77cfa5c5637a3acfcc73b853ba7b87591c5 Судя по всему - шеснадцатеричный код Далее эту строку нужно закодировать эту строку в Base64: Функция _КодироватьСтрокуВBase64(ИсходнаяСтрока) Экспорт ИмяВрФ = ПолучитьИмяВременногоФайла(); ЗаписьТекста = Новый ЗаписьТекста(ИмяВрФ, КодировкаТекста.ANSI); ЗаписьТекста.Записать(ИсходнаяСтрока); ЗаписьТекста.Закрыть(); Результат = Base64Строка(Новый ДвоичныеДанные(ИмяВрФ)); Попытка УдалитьФайлы(ИмяВрФ) Исключение КонецПопытки; Возврат Результат; конецфункции На выходе получаем не тот результат, который ожидаем. Возможно, что шеснадцатеричный код необходимо преобразовать в символьную строку, скорее всего utf8. Есть у кого какие соображения на этот счет? Как шеснадцатеричный код преобразовать в символьную строку utf8? |
|||
5
oleg_km
13.04.18
✎
15:07
|
Так ты и так используешь тот класс который я предложил, только через КОМ
Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA256"); |
|||
6
Puzoter
13.04.18
✎
15:31
|
(5) Да только ладу ему не дам с этими кодами и кодировками.
|
|||
7
Puzoter
13.04.18
✎
16:28
|
В общем ситуация с хешированием следующая:
И функция хэширования System.Security.Cryptography.HMACSHA256 и встроенная функция хэширования 1С: 8.3 возвращают строки типа: 41c9dd976bcfd8be539f40c0e250d77cfa5c5637a3acfcc73b853ba7b87591c5 Судя по всему - шеснадцатеричный код. Причем строки разные при одинаковых вводных - как так???? Далее полученный хэш нужно закодировать в Base64: Функция _КодироватьСтрокуВBase64(ИсходнаяСтрока) Экспорт ИмяВрФ = ПолучитьИмяВременногоФайла(); ЗаписьТекста = Новый ЗаписьТекста(ИмяВрФ, КодировкаТекста.ANSI); ЗаписьТекста.Записать(ИсходнаяСтрока); ЗаписьТекста.Закрыть(); Результат = Base64Строка(Новый ДвоичныеДанные(ИмяВрФ)); Попытка УдалитьФайлы(ИмяВрФ) Исключение КонецПопытки; Возврат Результат; Конецфункции При этом, опять таки, судя по всему, на вход Base64Строка() нужно давать символьную строку. Вопрос, в какой кодировке? Допустим в WIN-1251, тогда результат будет AЙЭϧkПШЎSϯ@АвPЧ|ъ\V7ϳϼьЗ;ϕ;ϷЈuϡЕ - длина 32 символа При этом хэш полученный в PHP: XеИЬНЊ УH:G#O]РzN®6…ЦБ - длина 22 символа Как же все-таки в 1С получить ХЭШ такой же, как в PHP? |
|||
8
tesseract
13.04.18
✎
16:56
|
(7)
>>Судя по всему - шеснадцатеричный код. Внезапно прямо, никто не ждал, что двоичные данные легко преобразуются в 16-ричный код. >>Допустим в WIN-1251, 1C работает со строками utf-8 по умолчанию. Даже в документации написано. |
|||
9
xXeNoNx
13.04.18
✎
17:06
|
(0)шо там, бота для биржи пишем?
|
|||
10
Puzoter
13.04.18
✎
17:08
|
(8) ну пусть utf8 - это ничего не меняет. Зачем что-то говорить, если по существу сказать нечего?
|
|||
11
xXeNoNx
13.04.18
✎
17:09
|
Мож как-нить так?
Функция DecToHex(Знач Число) тЧисло = Число; тБаза = 16; Пока тЧисло <> 0 Цикл тПоз =тЧисло % тБаза; Результат = Сред("0123456789abcdef", тПоз + 1, 1) + Результат; тЧисло = Цел(тЧисло / тБаза); КонецЦикла; Если Число < тБаза Тогда Результат = "0" + Результат; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьЗашифрованнуюСтроку(СтрокаШифрования, СекретныйКлюч) Текст = Новый COMОбъект("System.Text.UTF8Encoding"); КриптоSHA512 = Новый COMОбъект("System.Security.Cryptography.HMACSHA512"); КриптоSHA512.Key = Текст.GetBytes_4(СекретныйКлюч); Хэш = КриптоSHA512.ComputeHash_2(Текст.GetBytes_4(СтрокаШифрования)).Выгрузить(); ХэшСтрокой = ""; Для Каждого байт ИЗ Хэш Цикл ХэшСтрокой = ХэшСтрокой + DecToHex(байт); КонецЦикла; возврат ХэшСтрокой; КонецФункции |
|||
12
tesseract
13.04.18
✎
17:11
|
(10) Странно но любой алгоритм хэширования дает разные данные, в зависимости от кодировки. Может у кодировок в шестнадцатеричном коде коды другие?
|
|||
13
xXeNoNx
13.04.18
✎
17:11
|
+(11) Запили тока для 256
|
|||
14
Puzoter
13.04.18
✎
17:24
|
(13) Запилил. Результат отличается от
Функция ПолучитьХЭШ(ИсходнаяСтрока,Ключ) Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256); Хеширование.Добавить(ИсходнаяСтрока); //Хеширование.Добавить(Ключ); ТипКлюча = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "hexBinary"); ОбъектКлюча = ФабрикаXDTO.Создать(ТипКлюча, Хеширование.ХешСумма); СтроковыйКлюч = ОбъектКлюча.ЛексическоеЗначение; Если СтрДлина(СтроковыйКлюч) > 64 Тогда Сообщить("Превышение дланы ключа"); КонецЕсли; Возврат СтроковыйКлюч; КонецФункции Почему? |
|||
15
tesseract
13.04.18
✎
17:27
|
(14) потому что (8).
|
|||
16
Puzoter
13.04.18
✎
17:28
|
И остается вопрос: почему, если результат преобразовать в текст, не зависимо от кодировки строка будет из 32х символов. На сайте PHP ее будет сравнивать со своей строкой, а в ней 22 символа %)
|
|||
17
Puzoter
13.04.18
✎
17:31
|
(15) Да WIN-1251 я для примера привел, в программном коде эта кодировка нигде не используется. Просто закодировал HEX WIN-1251 и получил строку длиной 32 из сравнения со строкой из PHP. В utf-8 был бы тот же результат.
|
|||
18
Puzoter
13.04.18
✎
17:33
|
(15) По существу: где там кодировку указывать? И в ту и в другую функцию передается одна и та же строка в кодировке 1С (utf-8)
|
|||
19
tesseract
13.04.18
✎
17:36
|
>>И остается вопрос: почему, если результат преобразовать в текст, не зависимо от кодировки строка будет из 32х символов.
потому что длина блока у sha-256 - 512 бит. у sha-512 будет 64. >>В utf-8 был бы тот же результат. Это тебе Хрюша со Степашкой сказали? (16) Да нигде -F1 нажми у увидишь что в функцию хеширование должны попадать двоичные данные. А для utf/utf8/utf16/win1251/cp866 они таки разные. |
|||
20
Puzoter
13.04.18
✎
17:46
|
(19) Я по-моему ни где ни упоминал sha-512.
В Функции ПолучитьХЭШ(ИсходнаяСтрока,Ключ) Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256); Хеширование.Добавить(ИсходнаяСтрока); ИсходнаяСтрока - символьная, а не двоичная. |
|||
21
tesseract
13.04.18
✎
17:48
|
(20) У строки есть двоичные данные. Ее просто неявно преобразуют из UTF-8. Это указано в справке.
|
|||
22
Сияющий в темноте
13.04.18
✎
21:43
|
Я бы для начала посмотрел бы в интеинете генератор hash,чтобы понять кто из 1с или пхп криво генерит результат,очень похоже,что косячит пхр,т.к.у него по умолчанию однобайтовая кодировка,и если вы строку изначально в ютф8 не готовили,то будет фигня
|
|||
23
DmitriyDI
14.04.18
✎
11:19
|
(1) вот код работает 100%
Функция ЗашифроватьSHA512(Строка, СекретныйКлюч) Экспорт Текст = Новый COMОбъект("System.Text.UTF8Encoding"); Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA512"); Криптография.Key = Текст.GetBytes_4(СекретныйКлюч); ХешБайт = Криптография.ComputeHash_2(Текст.GetBytes_4(Строка)).Выгрузить(); Хеш = ""; Для Каждого Байт Из ХешБайт Цикл Символ = ЗакодироватьСтроку1С(Байт); Хеш = Хеш + ?(СтрДлина(Символ) = 2, Символ, "0"+Символ); КонецЦикла; Возврат НРег(Хеш); КонецФункции Функция ЗакодироватьСтроку1С(Знач ВходящееЧисло) База = 16; Результат = ""; Пока ВходящееЧисло <> 0 Цикл Поз =ВходящееЧисло % База; Результат = Сред("0123456789ABCDEF", Поз + 1, 1) + Результат; ВходящееЧисло = Цел(ВходящееЧисло / База); КонецЦикла; Возврат Результат; КонецФункции |
|||
24
DmitriyDI
14.04.18
✎
11:21
|
(23) а там 256, сори, тогда не подойдет
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |