Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

Помогите найти рабочий пример реализации HMACSHA256 в 1С:8.2

Помогите найти рабочий пример реализации HMACSHA256 в 1С:8.2
Я
   Puzoter
 
13.04.18 - 11:29
Задача - сделать запрос к сайту с использованием ХЭШа HMACSHA256.
Те примеры, которые я нашел почему-то возвращают результат, отличный от функции hash_hmac() PHP.
 
 
   oleg_km
 
1 - 13.04.18 - 13:32
   Puzoter
 
2 - 13.04.18 - 14:31
В hash_hmac() PHP используется два параметра - данные и секретный ключ, а в ХешированиеДанных() в 8.3 можно использовать ключ?
   Puzoter
 
3 - 13.04.18 - 14:32
(1) Это сложно слишком. Проще наверно поднять ПХП и делать к нему ГЕТ запрос.
   Puzoter
 
4 - 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?
   oleg_km
 
5 - 13.04.18 - 15:07
Так ты и так используешь тот класс который я предложил, только через КОМ
Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA256");
   Puzoter
 
6 - 13.04.18 - 15:31
(5) Да только ладу ему не дам с этими кодами и кодировками.
   Puzoter
 
7 - 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?
   tesseract
 
8 - 13.04.18 - 16:56
(7)
>>Судя по всему - шеснадцатеричный код.

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

>>Допустим в WIN-1251,

1C работает со строками  utf-8 по умолчанию.  Даже  в документации написано.
   xXeNoNx
 
9 - 13.04.18 - 17:06
(0)шо там, бота для биржи пишем?
   Puzoter
 
10 - 13.04.18 - 17:08
(8) ну пусть utf8 - это ничего не меняет. Зачем что-то говорить, если по существу сказать нечего?
 
 Рекламное место пустует
   xXeNoNx
 
11 - 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(байт);
    КонецЦикла;
    
    возврат ХэшСтрокой;
    
КонецФункции
   tesseract
 
12 - 13.04.18 - 17:11
(10)  Странно но любой алгоритм хэширования дает разные данные, в зависимости от кодировки. Может у кодировок в шестнадцатеричном коде коды другие?
   xXeNoNx
 
13 - 13.04.18 - 17:11
+(11) Запили тока для 256
   Puzoter
 
14 - 13.04.18 - 17:24
(13) Запилил. Результат отличается от

Функция ПолучитьХЭШ(ИсходнаяСтрока,Ключ)
    Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
    Хеширование.Добавить(ИсходнаяСтрока);
    //Хеширование.Добавить(Ключ);
    ТипКлюча = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema";, "hexBinary");
    ОбъектКлюча = ФабрикаXDTO.Создать(ТипКлюча, Хеширование.ХешСумма);
    СтроковыйКлюч = ОбъектКлюча.ЛексическоеЗначение;
    Если СтрДлина(СтроковыйКлюч) > 64 Тогда
        Сообщить("Превышение дланы ключа");
    КонецЕсли;
    Возврат СтроковыйКлюч;
КонецФункции

Почему?
   tesseract
 
15 - 13.04.18 - 17:27
(14) потому что (8).
   Puzoter
 
16 - 13.04.18 - 17:28
И остается вопрос: почему, если результат преобразовать в текст, не зависимо от кодировки строка будет из 32х символов. На сайте PHP ее будет сравнивать со своей строкой, а в ней 22 символа %)
   Puzoter
 
17 - 13.04.18 - 17:31
(15) Да WIN-1251 я для примера привел, в программном коде эта кодировка нигде не используется. Просто закодировал HEX WIN-1251 и получил строку длиной 32 из сравнения со строкой из PHP. В utf-8 был бы тот же результат.
   Puzoter
 
18 - 13.04.18 - 17:33
(15) По существу: где там кодировку указывать? И в ту и в другую функцию передается одна и та же строка в кодировке 1С (utf-8)
   tesseract
 
19 - 13.04.18 - 17:36
>>И остается вопрос: почему, если результат преобразовать в текст, не зависимо от кодировки строка будет из 32х символов.

потому что длина блока у sha-256 - 512 бит. у sha-512 будет 64.

>>В utf-8 был бы тот же результат.

Это тебе Хрюша со Степашкой сказали?

(16) Да нигде -F1 нажми у увидишь что в функцию хеширование должны попадать двоичные данные. А для utf/utf8/utf16/win1251/cp866  они таки разные.
   Puzoter
 
20 - 13.04.18 - 17:46
(19) Я по-моему ни где ни упоминал sha-512.

В Функции ПолучитьХЭШ(ИсходнаяСтрока,Ключ)
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить(ИсходнаяСтрока);

ИсходнаяСтрока - символьная, а не двоичная.
   tesseract
 
21 - 13.04.18 - 17:48
(20) У строки есть двоичные данные. Ее просто неявно преобразуют из UTF-8. Это указано в справке.
   Сияющий в темноте
 
22 - 13.04.18 - 21:43
Я бы для начала посмотрел бы в интеинете генератор hash,чтобы понять кто из 1с или пхп криво генерит результат,очень похоже,что косячит пхр,т.к.у него по умолчанию однобайтовая кодировка,и если вы строку изначально в ютф8 не готовили,то будет фигня
   DmitriyDI
 
23 - 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) + Результат;
        ВходящееЧисло = Цел(ВходящееЧисло / База);
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции
   DmitriyDI
 
24 - 14.04.18 - 11:21
(23) а там 256, сори, тогда не подойдет


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует