Несколько дней ломаю голову: в 1с при шифровании один результат, а в php другой.
Ошибка вроде как в кодировке, но как поправить не знаю.

ТОМУ, КТО ПЕРВЫЙ ДАСТ РЕШЕНИЕ ПЕРЕВЕДУ ПЯТИХАТКУ НА ТЕЛЕФОН ИЛИ КАРТУ ЗЕЛЕНОГО

Привожу код 1с:

```1c
    Функция ХешФункцияSHA512(Строка, СекретныйКлюч) Экспорт

    Текст = Новый COMОбъект("System.Text.UTF8Encoding");
    Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA512");
    Криптография.Key = Текст.GetBytes_4(СекретныйКлюч);

    ХешБайт = Криптография.ComputeHash_2(Текст.GetBytes_4(Строка)).Выгрузить();

    Хеш = ";
    Для Каждого Байт Из ХешБайт Цикл
    Символ = DecToHex(Байт);
    Хеш = Хеш + ДобавитьЛидирующиеНули(Символ, 2);
    КонецЦикла;

    Возврат Хеш;

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

    Функция ДобавитьЛидирующиеНули(Знач Строка, ЧислоСимволовПоФормату) Экспорт

    //Добавляет лидирующие нули

    ВозвращаемаяСтрока = Строка(Строка);
    ДлинаСтроки = СтрДлина(ВозвращаемаяСтрока);

    Для й = 1 По ЧислоСимволовПоФормату - ДлинаСтроки Цикл
    ВозвращаемаяСтрока = "0" + ВозвращаемаяСтрока;
    КонецЦикла;

    Возврат ВозвращаемаяСтрока;

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

    Функция DecToHex(Знач Число)

    // Функция переводит десятичное число в шестнадцатеричное

    Результат = ";
    Пока Число <> 0 Цикл
    Поз = Число % 16;
    Результат = Сред("0123456789abcdef", Поз + 1, 1) + Результат;
    Число = Цел(Число / 16);
    КонецЦикла;
    Возврат Результат;

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

Соответственно 2 вызова этой функции:
ХешФункцияSHA512("test", "123");
ХешФункцияSHA512("te$st", "123");

В первом случае вызов возвращает верное значение, во втором нет!

Аналогичный код в php:

```1c
    $sign = hash_hmac('sha512', "te$st", "123");
    print_r($sign);
```

Проверить код и результат в php можно здесь:
https://ideone.com/hJUtjm

Может найдется гуру с ответом в чем ошибка и как исправить.
Вариант с созданием файла для php не подходит
---
я тут на*овнокодил по-быстрому, главное работает и сходится с php)
уже интересно стало, что там может не работать, скорее всего назначение функции ПолучитьСтрокуИзДвоичныхДанных() другое и её нельзя здесь использовать

```1c
    Функция ХешФункцияSHA512(Строка, СекретныйКлюч) Экспорт

    Текст = Новый COMОбъект("System.Text.UTF8Encoding");
    Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA512");
    Криптография.Key = Текст.GetBytes_4(СекретныйКлюч);

    ХешБайт = Криптография.ComputeHash_2(Текст.GetBytes_4(Строка)).Выгрузить();

    Хеш = ";
    Для Каждого Байт Из ХешБайт Цикл
    Символ = DecToHex(Байт);
    Хеш = Хеш + ДобавитьЛидирующиеНули(Символ, 2);
    КонецЦикла;

    Возврат Хеш;

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

    Функция ХешФункцияSHA512Прямой(Строка, СекретныйКлюч) Экспорт

    Текст = Новый COMОбъект("System.Text.UTF8Encoding");
    Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA512");
    Криптография.Key = Hex1cToBytes(Строка(Base64Значение(СекретныйКлюч)));

    ХешБайт = Криптография.ComputeHash_2(Текст.GetBytes_4(Строка)).Выгрузить();

    Хеш = ";
    Для Каждого Байт Из ХешБайт Цикл
    Символ = DecToHex(Байт);
    Хеш = Хеш + ДобавитьЛидирующиеНули(Символ, 2);
    КонецЦикла;

    Возврат Хеш;

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

    Функция ДобавитьЛидирующиеНули(Знач Строка, ЧислоСимволовПоФормату) Экспорт

    //Добавляет лидирующие нули

    ВозвращаемаяСтрока = Строка(Строка);
    ДлинаСтроки = СтрДлина(ВозвращаемаяСтрока);

    Для й = 1 По ЧислоСимволовПоФормату - ДлинаСтроки Цикл
    ВозвращаемаяСтрока = "0" + ВозвращаемаяСтрока;
    КонецЦикла;

    Возврат ВозвращаемаяСтрока;

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

    Функция DecToHex(Знач Число)

    // Функция переводит десятичное число в шестнадцатеричное

    Результат = ";
    Пока Число <> 0 Цикл
    Поз = Число % 16;
    Результат = Сред("0123456789abcdef", Поз + 1, 1) + Результат;
    Число = Цел(Число / 16);
    КонецЦикла;
    Возврат Результат;

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

    Функция Hex1cToBytes(хекс1с)
    текЗнач = ";
    массивРез = Новый Массив;
    Для инд = 1 По СтрДлина(хекс1с) Цикл

    симв = Сред(хекс1с,инд,1);
    Если симв=" " Тогда
    массивРез.Добавить(HexToDec(текЗнач));
    текЗнач = ";
    Иначе
    текЗнач = текЗнач + симв;
    КонецЕсли;
    КонецЦикла;
    массивРез.Добавить(HexToDec(текЗнач));
    ВОзврат Новый COMSafeArray(массивРез,"VT_UI1",массивРез.Количество());
    КонецФункции

    Функция HexToDec(хекс)
    соотв = Новый Соответствие;
    соотв.Вставить("0",0);
    соотв.Вставить("1",1);
    соотв.Вставить("2",2);
    соотв.Вставить("3",3);
    соотв.Вставить("4",4);
    соотв.Вставить("5",5);
    соотв.Вставить("6",6);
    соотв.Вставить("7",7);
    соотв.Вставить("8",8);
    соотв.Вставить("9",9);
    соотв.Вставить("A",10);
    соотв.Вставить("B",11);
    соотв.Вставить("C",12);
    соотв.Вставить("D",13);
    соотв.Вставить("E",14);
    соотв.Вставить("F",15);
    стРазряд = соотв[Сред(хекс,1,1)];
    млРазряд = соотв[Сред(хекс,2,1)];

    Возврат стРазряд*16+млРазряд;
    КонецФункции
```
---
Фунция SHA512, принципиально?
Может использовать из готового CRC32, MD5, SHA1, SHA256?
---
принципиально )
---
Тогда здесь на Инфостарте есть что-то подобное
https://infostart.ru/public/175332/

```1c
    Текст = Новый COMОбъект("System.Text.UTF8Encoding");
    КриптоSHA512 = Новый COMОбъект("System.Security.Cryptography.SHA512Managed");
    Хэш = КриптоSHA512.ComputeHash_2(Текст.GetBytes_4("ололо")).Выгрузить();
```
---
я не гуру, но поигравшись немного с кодом на сайте ideone, понял, что проблема связана с символом $, а так как я не знаю PHP полез читать правила синтаксиса языка и почитав немного нашел в чем у вас ошибка, держите: http://php.net/manual/ru/language.types.string.php
Вкратце, нужно было писать "te\$st", тогда все сходится
---
ок, согласен. мой фэйл.
надо было в php писать: 'te$st'
по поводу вознаграждения отпишусь в личку
---
Однако, ошибка у меня еще осталась: следующий пример, который ближе к реальности:

ВОЗНАГРАЖДЕНИЕ ЭТОЙ ОШИБКИ ТАКОЕ ЖЕ )

1с:
СекретныйКлюч = "sO017E2K/s0VLtKNxd5HwOYbRdt/sA1Bv0QECa0+Wv7CHKDyKG0o7puTvP8­/OQA/Nr3dCvPUpztzOKc6/wXj+g==";
sign = ХешФункцияSHA512("тестовое сообщение", ПолучитьСтрокуИзДвоичныхДанных(Base64Значение(СекретныйКлюч)));

php:
$data1 = 'тестовое сообщение';
$secret = 'sO017E2K/s0VLtKNxd5HwOYbRdt/sA1Bv0QECa0+Wv7CHKDyKG0o7puTvP8­/OQA/Nr3dCvPUpztzOKc6/wXj+g==';
echo "base64_decode_secret: "; print_r(base64_decode($secret)); echo "\n";
$sign = hash_hmac('sha512', $data1, base64_decode($secret));
echo "sign: "; print_r($sign); echo "\n";

https://ideone.com/3RBruP

В чем здесь ошибка ? как правильно ?
---
а что за функция ПолучитьСтрокуИзДвоичныхДанных() и что у вас хранится в секретном ключе сейчас?
---
Секретный ключ написал же в коде
а функция ПолучитьСтрокуИзДвоичныхДанных() из встроенных (8.3.10):

ПолучитьСтрокуИзДвоичныхДанных(<ДвоичныеДанные>, <КодировкаТекста>)

Параметры:
<ДвоичныеДанные> (обязательный)

Тип: ДвоичныеДанные.
Двоичные данные, которые требуется преобразовать в строку.
<КодировкаТекста> (необязательный)

Тип: КодировкаТекста; Строка.
Кодировка текста может быть задана как в виде значения перечисления КодировкаТекста, так и в виде строки с указанием названия кодировки.
Значение по умолчанию: UTF8.

Возвращаемое значение:
Тип: Строка.

Описание:
Преобразует двоичные данные в строку с заданной кодировкой текста.

Доступность:
Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение(клиент), мобильное приложение(сервер).
---
я тут на*овнокодил по-быстрому, главное работает и сходится с php)
уже интересно стало, что там может не работать, скорее всего назначение функции ПолучитьСтрокуИзДвоичныхДанных() другое и её нельзя здесь использовать

```1c
    Функция ХешФункцияSHA512(Строка, СекретныйКлюч) Экспорт

    Текст = Новый COMОбъект("System.Text.UTF8Encoding");
    Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA512");
    Криптография.Key = Текст.GetBytes_4(СекретныйКлюч);

    ХешБайт = Криптография.ComputeHash_2(Текст.GetBytes_4(Строка)).Выгрузить();

    Хеш = ";
    Для Каждого Байт Из ХешБайт Цикл
    Символ = DecToHex(Байт);
    Хеш = Хеш + ДобавитьЛидирующиеНули(Символ, 2);
    КонецЦикла;

    Возврат Хеш;

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

    Функция ХешФункцияSHA512Прямой(Строка, СекретныйКлюч) Экспорт

    Текст = Новый COMОбъект("System.Text.UTF8Encoding");
    Криптография = Новый COMОбъект("System.Security.Cryptography.HMACSHA512");
    Криптография.Key = Hex1cToBytes(Строка(Base64Значение(СекретныйКлюч)));

    ХешБайт = Криптография.ComputeHash_2(Текст.GetBytes_4(Строка)).Выгрузить();

    Хеш = ";
    Для Каждого Байт Из ХешБайт Цикл
    Символ = DecToHex(Байт);
    Хеш = Хеш + ДобавитьЛидирующиеНули(Символ, 2);
    КонецЦикла;

    Возврат Хеш;

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

    Функция ДобавитьЛидирующиеНули(Знач Строка, ЧислоСимволовПоФормату) Экспорт

    //Добавляет лидирующие нули

    ВозвращаемаяСтрока = Строка(Строка);
    ДлинаСтроки = СтрДлина(ВозвращаемаяСтрока);

    Для й = 1 По ЧислоСимволовПоФормату - ДлинаСтроки Цикл
    ВозвращаемаяСтрока = "0" + ВозвращаемаяСтрока;
    КонецЦикла;

    Возврат ВозвращаемаяСтрока;

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

    Функция DecToHex(Знач Число)

    // Функция переводит десятичное число в шестнадцатеричное

    Результат = ";
    Пока Число <> 0 Цикл
    Поз = Число % 16;
    Результат = Сред("0123456789abcdef", Поз + 1, 1) + Результат;
    Число = Цел(Число / 16);
    КонецЦикла;
    Возврат Результат;

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

    Функция Hex1cToBytes(хекс1с)
    текЗнач = ";
    массивРез = Новый Массив;
    Для инд = 1 По СтрДлина(хекс1с) Цикл

    симв = Сред(хекс1с,инд,1);
    Если симв=" " Тогда
    массивРез.Добавить(HexToDec(текЗнач));
    текЗнач = ";
    Иначе
    текЗнач = текЗнач + симв;
    КонецЕсли;
    КонецЦикла;
    массивРез.Добавить(HexToDec(текЗнач));
    ВОзврат Новый COMSafeArray(массивРез,"VT_UI1",массивРез.Количество());
    КонецФункции

    Функция HexToDec(хекс)
    соотв = Новый Соответствие;
    соотв.Вставить("0",0);
    соотв.Вставить("1",1);
    соотв.Вставить("2",2);
    соотв.Вставить("3",3);
    соотв.Вставить("4",4);
    соотв.Вставить("5",5);
    соотв.Вставить("6",6);
    соотв.Вставить("7",7);
    соотв.Вставить("8",8);
    соотв.Вставить("9",9);
    соотв.Вставить("A",10);
    соотв.Вставить("B",11);
    соотв.Вставить("C",12);
    соотв.Вставить("D",13);
    соотв.Вставить("E",14);
    соотв.Вставить("F",15);
    стРазряд = соотв[Сред(хекс,1,1)];
    млРазряд = соотв[Сред(хекс,2,1)];

    Возврат стРазряд*16+млРазряд;
    КонецФункции
```
---
https://infostart.ru/public/713120/
вот тут подобная проблема решается, и есть такой коммент
Строка(ДвоичныеДанные) - так делать нельзя, т.к. съедаются #13#10

    // прочитаем двоичные данные в строку
    ТекстовыйДокумент = Новый ТекстовыйДокумент;
    ТекстовыйДокумент.Прочитать(ФайлДанных, "ISO-8859-1", "");
    ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
---
отлично, теперь вроде как работает. Спасибо !