logo Обзор КриптоПро NGate для защищённого доступа к корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline ыволавыд  
#1 Оставлено : 21 августа 2019 г. 17:49:24(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Добрый день,

Для взаимодействия со сторонним сервисом мне необходимо формировать POST-запрос включающий в себя
поля DigestValue и SignatureValue, формируемые по следующим правилам:
1. Вычислить хэш-сумму по ГОСТ Р 34.11-2012 и записать значение в DigestValue.
2. Подписать DigestValue по ГОСТ Р 34.10-2012 и записать значение в SignatureValue.

Для получения значения хэш-суммы используется следующий код:
CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101;

HashedData = Новый COMОбъект("CAdESCOM.HashedData");
HashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;

UTF8Encoding = Новый COMОбъект("System.Text.UTF8Encoding");
HashedData.Hash(UTF8Encoding.GetBytes_4(СтрокаДляФормированияДайджеста));

Хэш_HEXстрока = HashedData.Value;


Получаем хэш в формате HEX-строки, для передачи хэша в МенеджерКриптографии, необходимо перевести хэш в двоичные данные:
Хэш_ДвочиныеДанные = ПолучитьДвоичныеДанныеИзHexСтроки(Хэш_HEXстрока);

Дальше получаем значение подписи хэша:
МенеджерКриптографии = Новый МенеджерКриптографии("Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider", "", 80);
МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = "ХХХХХХХ";
Подпись_ДвочиныеДанные = МенеджерКриптографии.Подписать(ДайджестДвоичныеДанные, Сертификат);


Кодируем подпись в Base64:
ПодписьBase64 = Base64Строка(Подпись_ДвочиныеДанные);

Получившаяся подпись в Base64:
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

Проблема в том, что сторонний сервис ждет подпись вида:
rNTloWBbTsid1n9B1ANZ9/VasWJyg6jfiMeI12ERBSlOnzy6YFqMaa5nRb9ZrK9wbKimIBD70v8j8eP/tKn7/g==

Вопрос, как из подписи что получается у меня, получить подпись в том виде, который хочет сервис?
Или как надо формировать подпись чтобы сразу получался требуемый вид?




Offline two_oceans  
#2 Оставлено : 22 августа 2019 г. 4:19:46(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 33 раз
Поблагодарили: 130 раз в 125 постах
Добрый день.
По алгоритму есть непонятные места, в плане того что некоторые сервисы предполагают значение DigestValue подписать как хэш, а другие подписать как данные. Также немного сомнительно, что cadescom возвращает hex строку.
В любом случае, возможно продолжение операций в другом объекте cadescom, без менеджера криптографии. Если подписывать как хэш можно на подпись передать прямо HashedData, а если как данные, то надо от значения HashedData еще раз посчитать хэш, допустим в HashedData2 и передать на подпись HashedData2.
Цитата:
Проблема в том, что сторонний сервис ждет подпись вида:
rNTloWBbTsid1n9B1ANZ9/VasWJyg6jfiMeI12ERBSlOnzy6YFqMaa5nRb9ZrK9wbKimIBD70v8j8eP/tKn7/g==
Вопрос, как из подписи что получается у меня, получить подпись в том виде, который хочет сервис?
Это немного сложно, потому что сервис похоже ждет "чистое"("голое") значение подписи - 64 байта (88 символов в Base64) прямо от подписанных данных, а полученное значение может вообще не содержать подпись самих данных, а содержать атрибуты (в том числе хэш подписанных данных) и подпись атрибутов.

UPD: Само значение подписи - последние 64 байта в полученной через менеджеркриптографии подписи. Однако похоже подписаны атрибуты и скорее всего не подойдет.

Отредактировано пользователем 22 августа 2019 г. 4:44:25(UTC)  | Причина: Не указана

Offline ыволавыд  
#3 Оставлено : 22 августа 2019 г. 9:33:24(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Добрый день,

"69BFFED0A9415417CAD541E12784ED09B71966A90AA5D33D857B198F90C46A8C" это то что возвращает COM-объект COMОбъект("CAdESCOM.HashedData")
Нам подтвердили правильность получаемого хэша "ab/+0KlBVBfK1UHhJ4TtCbcZZqkKpdM9hXsZj5DEaow="

Формировать подпись пробовал еще тремя различными способами:
1. Через CAdESCOM.CadesSignedData
CADES_BES = 1;
CAPICOM_ENCODE_BASE64 = 0;

oSigner = Новый COMОбъект("CAdESCOM.CPSigner");
oSigner.Certificate = Сертификат;
oSigner.KeyPin = "ХХХХХХХ";

oSignedData = Новый COMОбъект ("CAdESCOM.CadesSignedData");
oSignedData.Content = ДанныеДляПодписи;

Возврат oSignedData.SignCades(oSigner, CADES_BES, True, CAPICOM_ENCODE_BASE64);


2. Через CAPICOM.SignedData
Signer = Новый COMОбъект("CAPICOM.Signer");
Signer.Certificate = Сертификат;
Signer.Options = 2;

SignedData = Новый COMОбъект("CAPICOM.SignedData");
SignedData.Content = ДанныеДляПодписи;

Возврат SignedData.Sign(Signer, True, CAPICOM_ENCODE_BASE64);


3. Через CAdESCOM.RawSignature
UTF8Encoding = Новый COMОбъект("System.Text.UTF8Encoding");

CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101;

oHashedData = Новый COMОбъект("CAdESCOM.HashedData");
oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;
oHashedData.Hash(UTF8Encoding.GetBytes_4(ДанныеДляПодписи));
oHashedData.SetHashValue(oHashedData.Value);

IRawSignature = Новый COMОбъект("CAdESCOM.RawSignature");

Возврат IRawSignature.SignHash(oHashedData, Сертификат);


Для первых двух способов результат тот же, что и МенеджерКриптографии, с помощью третьего способа получилась подпись требуемого вида, но ее забраковали объяснив так "В вашей подписи алгоритм NONEwithCryptoProSignature, а должен быть GOST3411_2012_256withGOST3410_2012_256CryptoProSignature_2012_256NONEwithGOST3410DH_2012_256"
Где в объекте RawSignature установить требуемый алгоритм я не нашел.
Offline two_oceans  
#4 Оставлено : 22 августа 2019 г. 12:05:28(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 33 раз
Поблагодарили: 130 раз в 125 постах
Автор: ыволавыд Перейти к цитате
Для первых двух способов результат тот же, что и МенеджерКриптографии
Если заказываете CADES_BES, то CADES_BES и получается.
Автор: ыволавыд Перейти к цитате
с помощью третьего способа получилась подпись требуемого вида, но ее забраковали объяснив так "В вашей подписи алгоритм NONEwithCryptoProSignature, а должен быть GOST3411_2012_256withGOST3410_2012_256CryptoProSignature_2012_256NONEwithGOST3410DH_2012_256"
Где в объекте RawSignature установить требуемый алгоритм я не нашел.
Какой-то очень длинный Вам назвали или это два? В полученном по третьему способу алгоритме смысл в том, что первая часть до with это алгоритм хэша, а вторая часть алгоритм подписи. Так как RawSignature при использовании SignHash не считает хэш, то честно ставит none вместо алгоритма хэша (дескать, я не вычислял хэш, [STRIKE]меня подставили[/STRIKE] мне его передали). Так как нужен алгоритм сложный, предположу что надо передавать значение хэша на метод подписи данных. У RawSignature такого не вижу, возможно надо хэшировать дважды.
Цитата:
oHashedData.SetHashValue(oHashedData.Value);
что-то не понял смысла этой строки, возможно она портит алгоритм. Двойное хэширование должно быть по другому.

Отредактировано пользователем 22 августа 2019 г. 12:11:24(UTC)  | Причина: Не указана

Offline ыволавыд  
#5 Оставлено : 22 августа 2019 г. 12:58:11(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Цитата:
Если заказываете CADES_BES, то CADES_BES и получается.

Получается подпись в таком виде "rNTloWBbTsid1n9B1ANZ9/VasWJyg6jfiMeI12ERBSlOnzy6YFqMaa5nRb9ZrK9wbKimIBD70v8j8eP/tKn7/g==" это не CADES_BES, тогда подскажите пожалуйста как называется требуемый вид?

По поводу объекта CAdESCOM.HashedData:

// инициализация объекта
oHashedData = Новый COMОбъект("CAdESCOM.HashedData");

// устанавливаем алгоритм хэширования
oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256; // 101

// проводим хэширование, на вход подается строка ДанныеДляПодписи = "Customer11533830831932E2C"
// переведенная в последовательность байтов с помощью UTF8Encoding.GetBytes_4(ДанныеДляПодписи)
oHashedData.Hash(UTF8Encoding.GetBytes_4(ДанныеДляПодписи));

// объект oHashedData инициализируется полученным значением хэша,
// в нашем случае "69BFFED0A9415417CAD541E12784ED09B71966A90AA5D33D857B198F90C46A8C"
oHashedData.SetHashValue(oHashedData.Value);

// Проинициализированный объект oHashedData подаем на вход метода SignHash объекта RawSignature
// совместно с сетификатом
ПодписанныйХэш = IRawSignature.SignHash(oHashedData, Сертификат)

и на выходе мы получаем подписанный хэш

Речь не идет о двойном хэшировании, по крайне мере мне его не надо. Очень интересно Ваше замечание по "NONEwithCryptoProSignature", почему может быть "None", вроде все делаю в соответствие с документацией CADESCOM https://cpdn.cryptopro.r...tent/cades/cadescom.html и хэш получается правильный, а подпись почему то неправильная, куда еще нужно копать?
Offline two_oceans  
#6 Оставлено : 24 августа 2019 г. 14:36:12(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 33 раз
Поблагодарили: 130 раз в 125 постах
88 символов в base64 это 64 байта "чистого" / "голого" / raw значения подписи. Все CADES начиная с самого простого CADES_BES в обязательном порядке имеют подписанные атрибуты. В принципе можно еще попробовать из доступных CADESCOM_PKCS7_TYPE - тоже не совсем то, но есть шанс что подписанных атрибутов не будет и тогда может быть подойдут последние 88/64 байт. Если base64 оканчивается на == можно просто скопировать 88 символов с конца считая с == ; если = одно или нет, придется декодировать из base64 брать последние 64 байта и снова кодировать base64.

Автор: ыволавыд Перейти к цитате
// проводим хэширование, на вход подается строка ДанныеДляПодписи = "Customer11533830831932E2C"
// переведенная в последовательность байтов с помощью UTF8Encoding.GetBytes_4(ДанныеДляПодписи)
oHashedData.Hash(UTF8Encoding.GetBytes_4(ДанныеДляПодписи));
Данная строка в любой кодировке одинакова, но все правильно (немного смущает четверка в названии метода).
Автор: ыволавыд Перейти к цитате
// объект oHashedData инициализируется полученным значением хэша,
// в нашем случае "69BFFED0A9415417CAD541E12784ED09B71966A90AA5D33D857B198F90C46A8C"
oHashedData.SetHashValue(oHashedData.Value);
Значение верное, но пожалуйста объясните этот шаг. Дело в том, что и oHashedData.Hash и oHashedData.SetHashValue изменяют внутреннее состояние объекта, то есть их использование на одном объекте взаимоисключающее - будет действовать эффект от последнего (.SetHashValue перезапишет полученное в .Hash значение хэша). Не могу сказать точно, возможно в данном случае значение oHashedData.Algorithm также сбросится. Более того, записывается то же самое значение, это как если бы написали "a=a;".

Есть 2 схемы использования:
Код:
1) oHashedData.Algorithm = ...;
oHashedData.Hash(...);
oHashedData.Value отправляется на удаленный компьютер или сохраняется либо oHashedData использкется в подписании
2) значение хэша загружается или получается с удаленного компьютера
oHashedData.Algorithm = ...:
oHashedData.SetHashValue(...);
oHashedData используется в подписании
У Вас получилось как будто схемы смешали. Рекомендую закомментировать строку oHashedData.SetHashValue(oHashedData.Value);

В коде (менеджер криптографии) вышло как раз двойное хэширование, так как на подпись подали хэш и менеджер ещё раз внутри прохэшировал. Этот факт перепроверил по приведенной длинной подписи из менеджеракриптографии: используя "Customer11533830831932E2C" как исходный текст - неверная подпись, декодируя hex от "69BFFED0A9415417CAD541E12784ED09B71966A90AA5D33D857B198F90C46A8C" как исходный текст - подпись верна. Потому если не нужно двойное хэширование надо в менеджер подавать "Customer11533830831932E2C". К слову, в подпись включен сертификат (и сертификат проходит проверку), который в другой теме замазан на скриншоте, так что если так важно скрыть, уберите длинное значение подписи из сообщения.

Отредактировано пользователем 24 августа 2019 г. 14:38:39(UTC)  | Причина: Не указана

Offline ыволавыд  
#7 Оставлено : 27 августа 2019 г. 1:00:13(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Спасибо за ответ.

Попробовал получить подпись без атрибутов, для этого использовал параметр реестра AddEsAttribute, параметр настраивал для использования совместно с cryptcp.x64.exe, насколько понял из описания, параметр влияет не только на cryptcp, но и на работу криптопровайдера в целом. Видимого эффекта данная настройка не оказала, атрибуты по прежнему включаются в подпись и проверку она не проходит.

На счет "oHashedData.SetHashValue(oHashedData.Value)", Вы были правы, SetHashValue применяется в случаях когда надо инициализировать объект уже имеющимся значением хэша. Попробовал без него совместно с методом RawSignature, результат отрицательный. Реализация:
UTF8Encoding = Новый COMОбъект("System.Text.UTF8Encoding");

CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101;

oHashedData = Новый COMОбъект("CAdESCOM.HashedData");
oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;
oHashedData.Hash(UTF8Encoding.GetBytes_4(ДанныеДляПодписи));

IRawSignature = Новый COMОбъект("CAdESCOM.RawSignature");
ЗначениеПодписи = IRawSignature.SignHash(oHashedData, Сертификат);


Пробовал получить реверс из ЗначениеПодписи, результат тоже отрицательный, сервис подпись не принимает.

Попробовал получить последние 64 байта из "длиной" подписи, проверку такая подпись тоже не прошла.

По поводу "UTF8Encoding.GetBytes_4", так 1С видит метод GetBytes у ком объекта COMОбъект("System.Text.UTF8Encoding").
Offline cross  
#8 Оставлено : 27 августа 2019 г. 13:55:55(UTC)
cross

Статус: Сотрудник

Группы: Администраторы, Участники
Зарегистрирован: 24.11.2009(UTC)
Сообщений: 908
Откуда: Crypto-Pro

Сказал(а) «Спасибо»: 3 раз
Поблагодарили: 144 раз в 133 постах
Это вам прислали идентификаторы из КриптоПро JCP.
Они обозначают следующее:

GOST3411*withGOST3410* - принимает данные, которые хеширует и подписывает
CryptoProSignature* - принимает данные, которые хеширует и подписывает, значение подписи при этом инвертированное (первый байт становится последним и так далее..)
NONEwithCryptoProSignature* - принимает готовый хеш и подписывает его, значение подписи при этом инвертированное
Анатолий Беляев (cross на cryptopro.ru)
Offline ыволавыд  
#9 Оставлено : 27 августа 2019 г. 15:17:46(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Делал инвертирование таким способом:
ИнвертированыйМассив = Новый Массив;
МассивДоичныхДанных = РазделитьДвоичныеДанные(Подпись_ДвочиныеДанные, 1);
Сч = МассивДоичныхДанных.Количество();
Пока Сч <> 0 Цикл
Сч = Сч - 1;
ИнвертированыйМассив.Добавить(МассивДоичныхДанных[Сч]);
КонецЦикла;

Возврат СоединитьДвоичныеДанные(ИнвертированыйМассив );


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

Проверку такая подпись не прошла

Отредактировано пользователем 27 августа 2019 г. 15:23:07(UTC)  | Причина: Не указана

Offline two_oceans  
#10 Оставлено : 28 августа 2019 г. 8:23:51(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 33 раз
Поблагодарили: 130 раз в 125 постах
Автор: ыволавыд Перейти к цитате
Делал инвертирование таким способом:
На вид похоже на правильное, можно уточнить Сч > 0. У меня сделано через обмен 2 чисел (до середины), что позволяет не заводить второй массив, точный текст навскидку не найду, примерно:
Код:
L:=A.length; // длина строки
j:=L;      // номер последнего байта, нумерация с 1
L:=L shr 1; // середина строки
for i:=1 to L do begin // с 1 до середины
  temp:=A[i];A[i]:=A[j];A[j]:=temp; // меняем A[i] и A[j]
  dec(j);
end;



Offline ыволавыд  
#11 Оставлено : 28 августа 2019 г. 12:17:34(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Решение интересное. Но как быть если в строке четное количество символов?
Сч равно количеству элементов массива, писать в новый массив надо начиная с последнего элемента массива
и надо остановиться когда элементы массива закончатся, поэтому запускается цикл следящий за состоянием переменной Сч,
значение которой на каждой итерации цикла уменьшается на единицу.
С начала записывается последний элемент массива с индексом Сч, потом с Сч-1 и так до тех пор пока Сч не станет равным 0.

Offline Санчир Момолдаев  
#12 Оставлено : 1 сентября 2019 г. 10:12:35(UTC)
Санчир Момолдаев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 03.12.2018(UTC)
Сообщений: 90
Российская Федерация

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 7 раз в 7 постах
Автор: ыволавыд Перейти к цитате
Делал инвертирование таким способом:
ИнвертированыйМассив = Новый Массив;
МассивДоичныхДанных = РазделитьДвоичныеДанные(Подпись_ДвочиныеДанные, 1);
Сч = МассивДоичныхДанных.Количество();
Пока Сч <> 0 Цикл
Сч = Сч - 1;
ИнвертированыйМассив.Добавить(МассивДоичныхДанных[Сч]);
КонецЦикла;

Возврат СоединитьДвоичныеДанные(ИнвертированыйМассив );


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

Проверку такая подпись не прошла


сравните длину входного и инвертированного массива.

Отредактировано пользователем 1 сентября 2019 г. 12:39:17(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline ыволавыд  
#13 Оставлено : 1 сентября 2019 г. 14:30:43(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Одинаковая, 88 символов в Base64 или 64 байта в ДвоичныеДанные
Offline two_oceans  
#14 Оставлено : 2 сентября 2019 г. 6:18:09(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 33 раз
Поблагодарили: 130 раз в 125 постах
Автор: ыволавыд Перейти к цитате
Решение интересное. Но как быть если в строке четное количество символов?
Сч равно количеству элементов массива, писать в новый массив надо начиная с последнего элемента массива
и надо остановиться когда элементы массива закончатся, поэтому запускается цикл следящий за состоянием переменной Сч,
значение которой на каждой итерации цикла уменьшается на единицу.
С начала записывается последний элемент массива с индексом Сч, потом с Сч-1 и так до тех пор пока Сч не станет равным 0.
Что-то запутали. Говорим одно и тоже, но на своих языках. У Вас между проверкой условия цикла и обращением к элементу массива МассивДвоичныхДанных[Сч] стоит уменьшение Сч, то есть последняя итерация на входе имеет Сч=1, потом Сч уменьшается до 0 и обращается к МассивДвоичныхДанных[0], все сходится. Заметьте, что переменная Сч не станет отрицительной, поэтому из Сч<>0 часть Сч<0 никогда не сработает, достаточно написать Сч>0 в условии цикла.

Пусть N число элементов массива, у меня вариант с нумерацией с 1 до N, у Вас с 0 до N-1. Что бы сделать из моего варианта 0 до N-1 надо просто вычесть единицу в 2 местах, вот так:
Код:
L:=A.length; // длина строки, поминаем как количество элементов, а не как номер последнего если нумерация с нуля!!!
j:=L-1;      // номер последнего байта, нумерация с 0
L:=(L shr 1)-1; // середина строки
for i:=0 to L do begin // с 0 до середины
  temp:=A[i];A[i]:=A[j];A[j]:=temp; // меняем A[i] и A[j]
  dec(j); // это j:=j-1; или j--;
end;


Четное или нечетное число элементов массива значение не имеет в силу специфики оператора shr 1, это сдвиг числа вправо на 1 бит, для положительных или беззнаковых чисел эффект как если бы число поделили пополам, но еще и теряется значение последнего бита (то есть как целочисленное деление на 2 без округления, на Бэйсике кажется это записывается как "N \ 2", направление черты не опечатка). Смотрите что выходит:
Если можно приведите исходное и инвертированное в Base64, что бы убедиться что соединилось все правильно (что-то не доверяю Бейсику).

Отредактировано пользователем 2 сентября 2019 г. 6:24:43(UTC)  | Причина: Не указана

Offline ыволавыд  
#15 Оставлено : 3 сентября 2019 г. 19:20:42(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

До реверса oDMaKFSCR1tE3rTXZb3X/6b5AbjbBBvf//m9Wm9wfJD2Wmk0ysRqx7gbI9Fa80WvJeKjl8IQmv6q0T7zbZzU6Q==
После gaCd35guiaMsxgELUVYRp90e79VJn5e6bZvfo43dVk3nvGhVK5CCziV1ijeGzbFzUlefi8ti7/VbBDGNxY8STQ==

Offline Андрей Писарев  
#16 Оставлено : 3 сентября 2019 г. 20:06:15(UTC)
Андрей Писарев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 8,246
Мужчина
Российская Федерация

Сказал «Спасибо»: 279 раз
Поблагодарили: 1154 раз в 912 постах
Автор: ыволавыд Перейти к цитате
До реверса oDMaKFSCR1tE3rTXZb3X/6b5AbjbBBvf//m9Wm9wfJD2Wmk0ysRqx7gbI9Fa80WvJeKjl8IQmv6q0T7zbZzU6Q==
После gaCd35guiaMsxgELUVYRp90e79VJn5e6bZvfo43dVk3nvGhVK5CCziV1ijeGzbFzUlefi8ti7/VbBDGNxY8STQ==




1)
A0 33 1A 28 54 82 47 5B 44 DE B4 D7 65 BD D7 FF
A6 F9 01 B8 DB 04 1B DF FF F9 BD 5A 6F 70 7C 90
F6 5A 69 34 CA C4 6A C7 B8 1B 23 D1 5A F3 45 AF
25 E2 A3 97 C2 10 9A FE AA D1 3E F3 6D 9C D4 E9

2)
81 A0 9D DF 98 2E 89 A3 2C C6 01 0B 51 56 11 A7
DD 1E EF D5 49 9F 97 BA 6D 9B DF A3 8D DD 56 4D
E7 BC 68 55 2B 90 82 CE 25 75 8A 37 86 CD B1 73
52 57 9F 8B CB 62 EF F5 5B 04 31 8D C5 8F 12 4D


???
Техническую поддержку оказываем тут
Наша база знаний
Offline ыволавыд  
#17 Оставлено : 3 сентября 2019 г. 22:36:36(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

1) kjXLuG+yQyGEZKgJJSgYv46wpKIie11L4+2OHWq38xExibOqVAqYE1SarYq8NGAjjmBeJ3PK0XfcyXChQQ8XIQ==
2) IRcPQaFwydx30cpzJ15gjiNgNLyKrZpUE5gKVKqziTER87dqHY7t40tdeyKipLCOvxgoJQmoZIQhQ7JvuMs1kg==

1) 92 35 CB B8 6F B2 43 21 84 64 A8 09 25 28 18 BF 8E B0 A4 A2 22 7B 5D 4B E3 ED 8E 1D 6A B7 F3 11 31 89 B3 AA 54 0A 98 13 54 9A AD 8A BC 34 60 23 8E 60 5E 27 73 CA D1 77 DC C9 70 A1 41 0F 17 21
2)21 17 0F 41 A1 70 C9 DC 77 D1 CA 73 27 5E 60 8E 23 60 34 BC 8A AD 9A 54 13 98 0A 54 AA B3 89 31 11 F3 B7 6A 1D 8E ED E3 4B 5D 7B 22 A2 A4 B0 8E BF 18 28 25 09 A8 64 84 21 43 B2 6F B8 CB 35 92
Offline two_oceans  
#18 Оставлено : 4 сентября 2019 г. 5:27:19(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 33 раз
Поблагодарили: 130 раз в 125 постах
Автор: ыволавыд Перейти к цитате
1) kjXLuG+yQyGEZKgJJSgYv46wpKIie11L4+2OHWq38xExibOqVAqYE1SarYq8NGAjjmBeJ3PK0XfcyXChQQ8XIQ==
2) IRcPQaFwydx30cpzJ15gjiNgNLyKrZpUE5gKVKqziTER87dqHY7t40tdeyKipLCOvxgoJQmoZIQhQ7JvuMs1kg==
Да, вот это правильный переворот.

Offline ыволавыд  
#19 Оставлено : 4 сентября 2019 г. 9:44:35(UTC)
ыволавыд

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2019(UTC)
Сообщений: 21

Понятно, спасибо

Так и не нашел способа сформировать подпись которая прошла бы у принимающей стороны,
финальный, на текущий момент, вариант алгоритма формирования подписи:
Код:

Хэш_HEXстрока = COMВычислитьХэшСуммуПоГОСТ_3411_2012(СтрокаДляФормированияДайджеста);
Хэш_ДвочиныеДанные = ПолучитьДвоичныеДанныеИзHexСтроки(Хэш_HEXстрока);
ХэшBase64 = Base64Строка(Хэш_ДвочиныеДанные);
	
Если СертификатCAdESCOM Тогда
 Сертификат = COMПолучитьСертификатCAdESCOM();
Иначе
 Сертификат = COMПолучитьСертификатCAPICOM();	
КонецЕсли;
	
oHashedData = Новый COMОбъект("CAdESCOM.HashedData");	
oHashedData.Algorithm = 101; // CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256
oHashedData.DataEncoding = 1; // CADESCOM_BASE64_TO_BINARY	
oHashedData.SetHashValue(Хэш_HEXстрока);		
	
IRawSignature = Новый COMОбъект("CAdESCOM.RawSignature");
Подпись_HEXстрока = IRawSignature.SignHash(oHashedData, Сертификат);
	                                                       
Подпись_ДвочиныеДанные = ПолучитьДвоичныеДанныеИзHexСтроки(Подпись_HEXстрока);
	
Если Реверс Тогда
 Подпись_ДвочиныеДанные = РеверсПодписи(Подпись_ДвочиныеДанные);	
КонецЕсли;
	
ПодписьBase64 = Base64Строка(Подпись_ДвочиныеДанные);
Offline two_oceans  
#20 Оставлено : 4 сентября 2019 г. 10:25:06(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 33 раз
Поблагодарили: 130 раз в 125 постах
Если все выглядит верно, но зашло в тупик, предлагаю суммировать известные данные.
Автор: ыволавыд Перейти к цитате
Для взаимодействия со сторонним сервисом мне необходимо формировать POST-запрос включающий в себя поля DigestValue и SignatureValue, формируемые по следующим правилам:
1. Вычислить хэш-сумму по ГОСТ Р 34.11-2012 и записать значение в DigestValue.
2. Подписать DigestValue по ГОСТ Р 34.10-2012 и записать значение в SignatureValue.

Проблема в том, что сторонний сервис ждет подпись вида:
rNTloWBbTsid1n9B1ANZ9/VasWJyg6jfiMeI12ERBSlOnzy6YFqMaa5nRb9ZrK9wbKimIBD70v8j8eP/tKn7/g==
Цитата:
с помощью третьего способа получилась подпись требуемого вида, но ее забраковали объяснив так "В вашей подписи алгоритм NONEwithCryptoProSignature, а должен быть GOST3411_2012_256withGOST3410_2012_256 CryptoProSignature_2012_256 NONEwithGOST3410DH_2012_256"
Автор: cross Перейти к цитате
идентификаторы из КриптоПро JCP. Они обозначают следующее:
GOST3411*withGOST3410* - принимает данные, которые хеширует и подписывает
CryptoProSignature* - принимает данные, которые хеширует и подписывает, значение подписи при этом инвертированное (первый байт становится последним и так далее..)
NONEwithCryptoProSignature* - принимает готовый хеш и подписывает его, значение подписи при этом инвертированное
Я все же не могу связно понять что с идентификаторами, которые прислали (там все-таки 3 идентификатора или один идентификатор), наверно правильный ответ должен быть в них. Версии пока: 1) принимающая сторона не принимает именно значение подписи? Хэш верный? или может быть надо перевернуть и хэш тоже? Только тот что идет на отправку или и тот что идет на подписание? В разных комбинациях с перевернутой и неперевернутой подписью:
Код:
а) Хэш_ДвочиныеДанные = РеверсПодписи(Хэш_ДвочиныеДанные)
ХэшBase64 = Base64Строка(Хэш_ДвочиныеДанные)
б) Хэш_ДвочиныеДанные = РеверсПодписи(Хэш_ДвочиныеДанные)
Хэш_HEXстрока=HEX(Хэш_ДвочиныеДанные)
ХэшBase64 = Base64Строка(Хэш_ДвочиныеДанные)
; 2) остается идея что авторы сервиса замудрили в описании и надо на самом деле вычислить хэш, потом хэш2 от хэша, потом подписать хэш2.

Отредактировано пользователем 4 сентября 2019 г. 10:32:51(UTC)  | Причина: Не указана

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.