Статус: Участник
Группы: Участники
Зарегистрирован: 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==
Вопрос, как из подписи что получается у меня, получить подпись в том виде, который хочет сервис? Или как надо формировать подпись чтобы сразу получался требуемый вид?
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Добрый день. По алгоритму есть непонятные места, в плане того что некоторые сервисы предполагают значение DigestValue подписать как хэш, а другие подписать как данные. Также немного сомнительно, что cadescom возвращает hex строку. В любом случае, возможно продолжение операций в другом объекте cadescom, без менеджера криптографии. Если подписывать как хэш можно на подпись передать прямо HashedData, а если как данные, то надо от значения HashedData еще раз посчитать хэш, допустим в HashedData2 и передать на подпись HashedData2. Цитата:Проблема в том, что сторонний сервис ждет подпись вида: rNTloWBbTsid1n9B1ANZ9/VasWJyg6jfiMeI12ERBSlOnzy6YFqMaa5nRb9ZrK9wbKimIBD70v8j8eP/tKn7/g== Вопрос, как из подписи что получается у меня, получить подпись в том виде, который хочет сервис? Это немного сложно, потому что сервис похоже ждет "чистое"("голое") значение подписи - 64 байта (88 символов в Base64) прямо от подписанных данных, а полученное значение может вообще не содержать подпись самих данных, а содержать атрибуты (в том числе хэш подписанных данных) и подпись атрибутов. UPD: Само значение подписи - последние 64 байта в полученной через менеджеркриптографии подписи. Однако похоже подписаны атрибуты и скорее всего не подойдет. Отредактировано пользователем 22 августа 2019 г. 4:44:25(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 установить требуемый алгоритм я не нашел.
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Автор: ыволавыд  Для первых двух способов результат тот же, что и МенеджерКриптографии Если заказываете 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)
| Причина: Не указана
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 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 и хэш получается правильный, а подпись почему то неправильная, куда еще нужно копать?
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
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)
| Причина: Не указана
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 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").
|
|
|
|
Статус: Сотрудник
Группы: Администраторы, Участники Зарегистрирован: 24.11.2009(UTC) Сообщений: 965 Откуда: Crypto-Pro
Сказал(а) «Спасибо»: 3 раз Поблагодарили: 174 раз в 152 постах
|
Это вам прислали идентификаторы из КриптоПро JCP. Они обозначают следующее:
GOST3411*withGOST3410* - принимает данные, которые хеширует и подписывает CryptoProSignature* - принимает данные, которые хеширует и подписывает, значение подписи при этом инвертированное (первый байт становится последним и так далее..) NONEwithCryptoProSignature* - принимает готовый хеш и подписывает его, значение подписи при этом инвертированное |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 17.08.2019(UTC) Сообщений: 21
|
Делал инвертирование таким способом: ИнвертированыйМассив = Новый Массив; МассивДоичныхДанных = РазделитьДвоичныеДанные(Подпись_ДвочиныеДанные, 1); Сч = МассивДоичныхДанных.Количество(); Пока Сч <> 0 Цикл Сч = Сч - 1; ИнвертированыйМассив.Добавить(МассивДоичныхДанных[Сч]); КонецЦикла;
Возврат СоединитьДвоичныеДанные(ИнвертированыйМассив );Получается с начала доичные данные разбираются побайтово в массив, после этого значения переносятся в другой массив в обратном порядке и из инвертированного массива получаем двоичные данные в нужном представлении Проверку такая подпись не прошла Отредактировано пользователем 27 августа 2019 г. 15:23:07(UTC)
| Причина: Не указана
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Автор: ыволавыд  Делал инвертирование таким способом: На вид похоже на правильное, можно уточнить Сч > 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;
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close