logo Наши способы организации безопасного удалённого доступа к рабочим местам и корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Входит на форум или Регистрация.

Уведомление

Icon
Error

4 Страницы<1234>
Опции
К последнему сообщению К первому непрочитанному
Offline user100000  
#41 Оставлено : 7 февраля 2019 г. 2:36:08(UTC)
user100000

Статус: Новичок

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

не появились нормальные средство канонизации?
или скиньте dll от С++
Offline two_oceans  
#42 Оставлено : 7 февраля 2019 г. 6:43:25(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах
Вроде бы нет, есть куча самопальных, реализующих c14n не полностью, то есть выдающих правильные данные для конкретных типов запросов, но для других запросов неизвестно будет ли ответ верным, так как в них могут быть нужны неподдерживаемые реализацией части c14n. Свой вариант реализации при ошибках проверяю программкой c14n.exe от slawv (на основе dotNet 4.5 и выше). С трансформом СМЭВ 3 дела еще хуже - там и алгоритм неподробно описан и тесты не очень точные.

Offline user100000  
#43 Оставлено : 8 февраля 2019 г. 12:35:15(UTC)
user100000

Статус: Новичок

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

Автор: two_oceans Перейти к цитате
Вроде бы нет, есть куча самопальных, реализующих c14n не полностью, то есть выдающих правильные данные для конкретных типов запросов, но для других запросов неизвестно будет ли ответ верным, так как в них могут быть нужны неподдерживаемые реализацией части c14n. Свой вариант реализации при ошибках проверяю программкой c14n.exe от slawv (на основе dotNet 4.5 и выше). С трансформом СМЭВ 3 дела еще хуже - там и алгоритм неподробно описан и тесты не очень точные.


использовал uXMLHelper.pas - все работает
по крайней мере метод getPrivateLNData
Offline delem  
#44 Оставлено : 20 января 2020 г. 23:00:54(UTC)
delem

Статус: Новичок

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

Сказал(а) «Спасибо»: 1 раз
Помогите, люди добрые.
Пытаюсь победить сервис ФСС со стороны МО.
Запрос на получение номера ЛН с подписью проходит проверку корректно getNewLNNum.xml (7kb) загружен 3 раз(а).
По аналогии формирую запрос на отправку больничного листа - prParseFilelnlpu.xml (9kb) загружен 5 раз(а).
Проверку не проходит, подпись недействительна.
Что я делаю не так, не могу разобраться.
В первом случае нужно подписывать весь блок <body>, во втором подписывается блок <ROW>, все согласно спецификации.
Для канноникализации используется uXMLHelper.pas, проверял с помощью c14n.exe - изменений никаких в xml не вносит.
Проверяю с помощью https://www.justsign.me/verifyqca/Verify/
Чтобы я не делал - XML подпись не верна
Offline two_oceans  
#45 Оставлено : 22 января 2020 г. 19:16:23(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах
Одна из ошибок очевидна. Во втором файле prParseFilelnlpu.xml у Вас два раза указано одно и то же значение для Id - в теге BODY и в теге ROW. Это нарушает стандарт XML - Id должно иметь уникальное значение в пределах документа. Программы интерпретирующие и проверяющие подпись скорее всего заточены на быстродействие и после того как нашли Body далее предполагают что документ соответвует стандарту и значение больше не встретится, поэтому не будут искать это значение Id в ROW. Очевидно, что значение хэша для Body получится совсем другое чем для Row.

Вторая проблема в том, что даже если убрать Id в Body и правильно выберется фрагмент Row у меня все равно выходит другой хэш. Над этим еще подумаю.

Отредактировано пользователем 22 января 2020 г. 19:30:43(UTC)  | Причина: Не указана

Offline delem  
#46 Оставлено : 22 января 2020 г. 20:08:43(UTC)
delem

Статус: Новичок

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

Сказал(а) «Спасибо»: 1 раз
Моя ошибка. Пробою разные варианты, подписывать <body>, вместо <row>, пусть хоть фсс не примет, но проверка криптопро пройдет. Не поменял шаблон. Канноникализация c14n.exe не изменяет абсолютно ничего. Проверял на этапе формирования значения digest value через https://www.cryptopro.ru...ades_xmldsig_sample.html - все совпадает. И в первом и во втором файле. Не понятно, почему один файл пропускает, а второй аналогичный нет.
Вот правильный неправильный второй файл prParseFilelnlpu.xml (9kb) загружен 1 раз(а).
Offline two_oceans  
#47 Оставлено : 22 января 2020 г. 20:27:09(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах

Для поправленного файла после каноникализации получаю такой текст с хэшем
5F7D DC5B 8305 1DDF C34F B678 342E D5C4 40DF B9B0 360C A9B3 F998 692F CEBE 2123
X33cW4MFHd/DT7Z4NC7VxEDfubA2DKmz+ZhpL86+ISM=
Offline delem  
#48 Оставлено : 22 января 2020 г. 20:59:24(UTC)
delem

Статус: Новичок

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

Сказал(а) «Спасибо»: 1 раз
Точно, спасибо, получил правильный файл prParseFilelnlpu.xml (18kb) загружен 3 раз(а).
Оказывается, каноникализация в uXMLHelper.pas ломала мне его, отключил ее совсем, формирую xml сразу правильной структуры.
Теперь при расщифровке ответа от ФСС - плохие данные, хотя с первым файлом ошибок нет, копаем дальше...
Offline two_oceans  
#49 Оставлено : 24 января 2020 г. 12:26:12(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах
В первом файле по сути нечего каноникализировать - почти никакие пункты c14n не применяются.
Генерировать сразу канонизированный текст конечно можно, но тут может быть конфилкт с некоторыми ИС, которые требуют строго определенного порядка атрибутов, отличного от канонического.
Если будете проверять подпись ответа (как задумывается в любой ИС), то без c14n не обойтись, так как ИС будет слать не обязательно каноничный текст.

В новом файле первая подпись проверяется полностью (математически верны SignatureValue и DigestValue), на второй подписи у меня вылетает ошибка.
UPD: ошибка была в моей программе. Суть в том, что в данном файле один сертификат включен 2 раза с разными Id. Моя программа определяла, что сертификат уже загружен и не добавляла второй экземпляр с новым Id, потому Id не находился. Исправил, теперь вторая и третья подписи также проверились (математически верны).

Отредактировано пользователем 27 января 2020 г. 22:57:39(UTC)  | Причина: Не указана

Offline DonCossack  
#50 Оставлено : 30 января 2020 г. 15:57:04(UTC)
DonCossack

Статус: Новичок

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

Сказал(а) «Спасибо»: 3 раз
Всем добрый день!

Запрос не проходит проверку, подпись недействительна.
Проверяю с помощью https://www.justsign.me/verifyqca/Verify/
Окончательно зашел в тупикBrick wall
Для формирования xml использую описание этой ветки форума и юнит UCryptHelper.pas,
в котором для ГОСТ 2012 добавил константу PROV_GOST_2012_256 = 80.
В чем дело, не пойму, <body> достаточно прозрачный
xml по ссылке (приаттачить к посту не получается):
http://seafile.mosgorbti.ru:8000/f/a0bb9a8849/?raw=1

Буду благодарен за любые советы, куда смотреть
Offline two_oceans  
#51 Оставлено : 30 января 2020 г. 16:54:20(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах
Автор: DonCossack Перейти к цитате
Для формирования xml использую описание этой ветки форума и юнит UCryptHelper.pas,
в котором для ГОСТ 2012 добавил константу PROV_GOST_2012_256 = 80.
В чем дело, не пойму, <body> достаточно прозрачный
xml по ссылке (приаттачить к посту не получается):
file
Буду благодарен за любые советы, куда смотреть
Добрый день.
1. Под узлом xml все заменено на &lt; &gt; возможно дело в этом. Моя программа не может это переварить корректно, так как я не реализовывал данный пункт алгоритма C14N приведения к канонической форме. Поясню суть пункта: для корректной канонической формы нужно сначала поменять все RefChar и EntityChar которыми в частности являются &lt; &gt; на сами символы < >, потом поменять обратно на каноничный вид RefChar те символы, которые запрещены в конкретном месте документа (в данном случае в текстовом узле). Если правильно понимаю, < станет &#x3С; а > останется как есть. Полагаю, вспомогательные юниты возможно тоже не реализуют этот пункт алгоритма C14N.

2. Возможно дело в перевороте значения подписи - в моей программе при проверке автоматически производится переворот декодированного из Base64 значения SignatureValue (стандарт подписи указывает тип в котором значение должно быть Big Endian, в то время как КриптоПро возвращает Little Endian). При подписании аналогично - переворот перед кадированием в Base64. Хэш проходит без переворота, хотя с ним по идее такая же история, но большинство сервисов использует тоже КриптоПро и игнорируют такую малость.

по SignedInfo вышла каноническая форма и хэш:
Код:
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"></ds:SignatureMethod><ds:Reference URI="#body"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"></ds:DigestMethod><ds:DigestValue>MY9AZhgIgu5LtaOxDxzQHm/WDZ1o5DupakHh+f+aZQ8=</ds:DigestValue></ds:Reference></ds:SignedInfo>
Код:
AA0E B779 8464 9438 85E7 8510 24E9 4685 2806 61BD 1BF3 07C6 984B DF37 C417 20ED
[qg63eYRklDiF54UQJOlGhSgGYb0b8wfGmEvfN8QXIO0=]
С переворотом:
ED20 17C4 37DF 4B98 C607 F31B BD61 0628 8546 E924 1085 E785 3894 6484 79B7 0EAA
[7SAXxDffS5jGB/MbvWEGKIVG6SQQheeFOJRkhHm3Dqo=]

но дальше проверка SignatureValue не прошла.

3. На всякий случай. Кроме замены типа провайдера 75 на 80, заменить надо еще и хэш алгоритм на 32801.

Отредактировано пользователем 31 января 2020 г. 3:26:59(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
DonCossack оставлено 31.01.2020(UTC)
Offline DonCossack  
#52 Оставлено : 31 января 2020 г. 12:15:41(UTC)
DonCossack

Статус: Новичок

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

Сказал(а) «Спасибо»: 3 раз
Добрый день!
1. Узел xml убрал совсем, результат тот же.
ссылка на xml :
http://seafile.mosgorbti.ru:8000/f/a0bb9a8849/?raw=1

Т.е дело не в нем или не только в нем

2. Как я понимаю,хэш body у нас совпадает

3. Скорей всего я что-то напутал в uCryptHelper.pas
Я изменил тип провайдера на 80 - PROV_GOST_2012_256 = 80;
и добавил ALG_SID_GR3411_2012_256 = 33;
ссылка на uCryptHelper.pas:
http://seafile.mosgorbti.ru:8000/f/d30ee508b2/?raw=1

Как заменить хэш алгоритм на 32801 не пойму Anxious
Offline two_oceans  
#53 Оставлено : 31 января 2020 г. 13:48:15(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах
Автор: DonCossack Перейти к цитате
Добрый день!
1. Узел xml убрал совсем, результат тот же.
ссылка на xml :
http://seafile.mosgorbti.ru:8000/f/a0bb9a8849/?raw=1
Т.е дело не в нем или не только в нем
Вероятно не только в нем, ведь SignatureValue не проверилось, а оно не зависит напрямую от body. Сейчас посмотрю подробнее как с новым файлом.
Автор: DonCossack Перейти к цитате
2. Как я понимаю,хэш body у нас совпадает
Нет, раз уж я заведомо не реализовывал нужный пункт C14N то в прошлом примере сравнивать Body не имело смысл: хэш отличался, но у меня был заведомо неверен.
Автор: DonCossack Перейти к цитате
3. Скорей всего я что-то напутал в uCryptHelper.pas
Я изменил тип провайдера на 80 - PROV_GOST_2012_256 = 80;
и добавил ALG_SID_GR3411_2012_256 = 33;
ссылка на uCryptHelper.pas:
http://seafile.mosgorbti.ru:8000/f/d30ee508b2/?raw=1

Как заменить хэш алгоритм на 32801 не пойму Anxious
Смотрите ALG_CLASS_HASH = 4 shl 13; в шестнадцатиричной записи это будет ALG_CLASS_HASH = $8000;
ALG_SID_GR3411_2012_256 = 33; в шестнадцатиричной будет $21
CALG_GR3411_2012_256 = ALG_CLASS_HASH or ALG_SID_GR3411_2012_256; то есть $8000 or $21 = $8021
$8021 это 32801, все сходится. Для проверки можно вычислить хэш от пустой строки:
3F53 9A21 3E97 C802 CC22 9D47 4C6A A32A 825A 360B 2A93 3A94 9FD9 2520 8D9C E1BB
[P1OaIT6XyALMIp1HTGqjKoJaNgsqkzqUn9klII2c4bs=]

На первый взгляд вроде в порядке, но конечно в который раз вижу и все удивляет функция-комбаин GetHashStream. Если нужно только вычислить хэш без подписания, можно CryptAcquireContext вызвать попроще: без имени контейнера и с флагом CRYPT_VERIFYCONTEXT как в GetProvContainers. Еще одно слабое место dwKeySpec прописанный в коде. Так можно вычислить хэш проще:
Код:
procedure GetOnlyHashStream(DataStream: TStream; HashStream: TStream);
var
  hProv: HCRYPTPROV;
  DataLen: DWORD;
  hHash: HCRYPTHASH;
  InStream, OutStream: TBytesStream;
begin
  InStream:=TBytesStream.Create;
  OutStream:=TBytesStream.Create;
  try

    CopyStream(DataStream,InStream);

    CryptCheck(CryptAcquireContext(@hProv, nil, nil, PROV_GOST_2012_256, CRYPT_VERIFYCONTEXT), 'CryptAcquireContext'); // PROV_GOST_2001_DH

    try

      if HashStream<>nil then
      begin

        CryptCheck(CryptCreateHash(hProv, CALG_GR3411_2012_256, 0, 0, @hHash), 'CryptCreateHash');    //CALG_GR3411
        try

          CryptCheck(CryptHashData(hHash, InStream.Memory, InStream.Size, 0), 'CryptHashData');

          //получение хеша

            CryptCheck(CryptGetHashParam(hHash, HP_HASHVAL, nil, @DataLen, 0), 'CryptGetHashParam');
            OutStream.Size:=DataLen;
            CryptCheck(CryptGetHashParam(hHash, HP_HASHVAL, OutStream.Memory, @DataLen, 0), 'CryptGetHashParam');
            CopyStream(OutStream,HashStream);

        finally
          CryptCheck(CryptDestroyHash(hHash), 'CryptDestroyHash');
        end;

      end;

    finally
      CryptCheck(CryptReleaseContext(hProv, 0), 'CryptReleaseContext');
    end;

  finally
    InStream.Free;
    OutStream.Free;
  end;

end;

Переворот подписи на месте, значит если и есть ошибка, то вероятно в каноникализации.

Отредактировано пользователем 1 февраля 2020 г. 2:26:36(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
DonCossack оставлено 03.02.2020(UTC)
Offline DonCossack  
#54 Оставлено : 31 января 2020 г. 14:42:28(UTC)
DonCossack

Статус: Новичок

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

Сказал(а) «Спасибо»: 3 раз
приведу кусок кода, чтобы уже совсем все было прозрачно:

BodyContext := '<s:Body Id="body"><setDataIn xmlns="http://ehd.mos.com/"></setDataIn></s:Body>';

DataStream:=TStringStream.Create(BodyContext,TEncoding.UTF8);
Hash:=TBytesStream.Create;
try
//вычисление хеша блока <Body>
CryptContainer :='\\.\REGISTRY\BTI2020';
GetHashStream(CryptContainer,DataStream,nil,nil,Hash,nil);
//блок для подписи
SignedInfo:= '<ds:SignedInfo>'
+' xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'
+'<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>'
+'<ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"></ds:SignatureMethod>'
+'<ds:Reference URI="#body">'
+'<ds:Transforms>'
+'<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>'
+'</ds:Transforms>'
+'<ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"></ds:DigestMethod>'
+'<ds:DigestValue>'

+ AsBase64(Hash)

+'</ds:DigestValue>'
+'</ds:Reference>'
+'</ds:SignedInfo>';

finally
DataStream.Free;
Hash.Free;
end;

DataStream:=TStringStream.Create(SignedInfo,TEncoding.ansi);//UTF8);

Cert:=TBytesStream.Create;
Sign:=TBytesStream.Create;
try
//подпись <SignedInfo> и получение данных сертификата
GetHashStream(CryptContainer,DataStream,Cert,nil,nil,Sign);
Header :='<s:Header>'
+'<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"'
+' s:actor="http://smev.gosuslugi.ru/actors/smev" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">'
+ '<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"'
+ ' EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"'
+ ' ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"'
+' wsu:Id="SenderCertificate">'

+ AsBase64(Cert)

+ '</wsse:BinarySecurityToken><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'

+ SignedInfo

+ '<ds:SignatureValue>' + AsBase64(Sign) + '</ds:SignatureValue>'
+ '<ds:KeyInfo>' + '<wsse:SecurityTokenReference>'
+ '<wsse:Reference URI="#SenderCertificate" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">'
+ '</wsse:Reference>'
+ '</wsse:SecurityTokenReference>'
+ '</ds:KeyInfo>'
+ '</ds:Signature>'
+ '</wsse:Security>'
+ '</s:Header>';

finally
DataStream.Free;
Cert.Free;
Sign.Free;
end;


Offline two_oceans  
#55 Оставлено : 1 февраля 2020 г. 1:26:07(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах
Автор: DonCossack Перейти к цитате
приведу кусок кода, чтобы уже совсем все было прозрачно:

Да, так яснее в чем дело: в коде вообще нет каноникализации, хотя в самой результирующей подписи указана эксклюзивная каноникализация. Итак по порядку:
Автор: DonCossack Перейти к цитате
BodyContext := '<s:Body Id="body"><setDataIn xmlns="http://ehd.mos.com/"></setDataIn></s:Body>';
В каноническом виде в <s:Body Id="body"> должно быть объявление пространства имен, в остальном такой короткий текст уже каноничен.
Код:
<s:Body xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" Id="body">
Если поменяется Id на wsu:Id, то
Код:
<s:Body xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="body">
Идея в том, что фрагмент идущий на вычисление хэша должен быть самодостаточным и содержать все объявления используемых пространств имен и соответственно без неиспользуемых и в правильных местах. В документ можно писать как есть без добавления, а вот на вычисление хэша должно идти с добавкой, так как сервис проверки проведет каноникализацию перед вычислением хэша и добавит текст. То есть если все делать по стандарту у Вас тоже должна быть каноникализация между этой строкой и вызовом GetHashStream. С учетом разной записи в документ даже наверно между загрузкой в DataStream и вызовом GetHashStream.
Автор: DonCossack Перейти к цитате
GetHashStream(CryptContainer,DataStream,nil,nil,Hash,nil);
Это то место, где можно хэш вычислить попроще. Как попроще добавлю в прошлое сообщение. В виде как есть - вероятно будут лишние запросы пин-кода на контейнер.
Автор: DonCossack Перейти к цитате
SignedInfo:= '<ds:SignedInfo>'
...
+'<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
...
+'<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>'
...
+'</ds:SignedInfo>';
Аналогично s:Body для ds:SignedInfo тоже нужна каноникализация до GetHashStream. Каноникализация указана в строках выделенных жирным. В данном случае на вычисление хэша/подписи должно пойти с объявлением пространства имен, в остальном текст уже каноничен.
Код:
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#>
После модификации s:Body, ds:SignedInfo подпись по идее будет проверяться сервисом, но если планируете проверять ответы, то лучше позаботиться о более полноценной каноникализации.
Автор: DonCossack Перейти к цитате
//подпись <SignedInfo> и получение данных сертификата
GetHashStream(CryptContainer,DataStream,Cert,nil,nil,Sign);
Примечание: Тут на момент отладки удобно передать стрим Hash2 чтобы сравнить хэш от SignedInfo, так как значение Sign не получится сравнить напрямую.
Автор: DonCossack Перейти к цитате
+' s:actor="http://smev.gosuslugi.ru/actors/smev" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">'
Примечание: Атрибут s:actor="http://smev.gosuslugi.ru/actors/smev" зависит от информационной системы в которую отправляете запрос. В данном случае это подпись информационной системы участника СМЭВ 2(отправителя), адресованная в СМЭВ. Для сервиса проверки подписи не приципиально наличие этого атрибута, а вот информационная система по нему проверяет какая подпись за что отвечает, если в документе несколько подписей. Вообще структура с заключением Signature в wsse:Securuity это также требование СМЭВ 2, но не СМЭВ 3.

Отредактировано пользователем 1 февраля 2020 г. 2:35:41(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
DonCossack оставлено 01.02.2020(UTC)
Offline DonCossack  
#56 Оставлено : 3 февраля 2020 г. 10:55:20(UTC)
DonCossack

Статус: Новичок

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

Сказал(а) «Спасибо»: 3 раз
Добрый день!

в <body> добавил пространство имен:
BodyContext :=
'<s:Body xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" Id="body"><setDataIn xmlns="http://ehd.mos.com/"></setDataIn></s:Body>';

т.е, body считаем каноникализированным.

Далее
DataStream:=TStringStream.Create(BodyContext,TEncoding.UTF8);
Hash:=TBytesStream.Create;
GetOnlyHashStream(DataStream,Hash); // использую Вашу процедуру

Блок для подписи не менял, как я понял , он каноникализированный, объявление присутствует:
SignedInfo:= '<ds:SignedInfo>'
+' xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'
+'<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>'
+'<ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"></ds:SignatureMethod>'
+'<ds:Reference URI="#body">'
+'<ds:Transforms>'
+'<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>'
+'</ds:Transforms>'
+'<ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"></ds:DigestMethod>'
+'<ds:DigestValue>'
+ AsBase64(Hash)
+'</ds:DigestValue>'
+'</ds:Reference>'
+'</ds:SignedInfo>';

но получаю ошибку при про проверке на https://www.justsign.me/verifyqca/Verify/ : подпись недействительна
ссылка xml :
http://seafile.mosgorbti.ru:8000/f/a0bb9a8849/?raw=1



Offline DonCossack  
#57 Оставлено : 3 февраля 2020 г. 13:33:49(UTC)
DonCossack

Статус: Новичок

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

Сказал(а) «Спасибо»: 3 раз
Нашел ошибку!

Вы писали:
Аналогично s:Body для ds:SignedInfo тоже нужна каноникализация до GetHashStream

блок SignedInfo был не кановализирован Anxious

Two_oceans огромное спасибоApplause
Offline two_oceans  
#58 Оставлено : 4 февраля 2020 г. 8:04:41(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 62 раз
Поблагодарили: 219 раз в 206 постах
Автор: DonCossack Перейти к цитате
Нашел ошибку! блок SignedInfo был не кановализирован Anxious
Two_oceans огромное спасибоApplause
Пожалуйста. Я тоже ошибку не увидел, хотя программа выдала нечто похожее на объявление в текстовом узле. Символ > технически не запрещен, так что не знаю как такую ситуацию выловить. Теоретически может частично помочь вывод необработанного содержимого в теге Signature.

Для протокола, ошибка здесь:
Код:
SignedInfo:= '<ds:SignedInfo>'
+' xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'
Правильно не закрывать тег в первой строке, тег продолжается во второй строке:
Код:
SignedInfo:= '<ds:SignedInfo'
+' xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'

Отредактировано пользователем 4 февраля 2020 г. 8:15:21(UTC)  | Причина: Не указана

Offline DonCossack  
#59 Оставлено : 4 февраля 2020 г. 8:36:52(UTC)
DonCossack

Статус: Новичок

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

Сказал(а) «Спасибо»: 3 раз
Да, именно там ошибка.
Сейчас делаю отладку блока xml

Вы писали:
1. Под узлом xml все заменено на &lt; &gt; возможно дело в этом. Моя программа не может это переварить корректно, так как я не реализовывал данный пункт алгоритма C14N приведения к канонической форме. Поясню суть пункта: для корректной канонической формы нужно сначала поменять все RefChar и EntityChar которыми в частности являются &lt; &gt; на сами символы < >, потом поменять обратно на каноничный вид RefChar те символы, которые запрещены в конкретном месте документа (в данном случае в текстовом узле). Если правильно понимаю, < станет &#x3С; а > останется как есть. Полагаю, вспомогательные юниты возможно тоже не реализуют этот пункт алгоритма C14N.

По итогам отпишусь
Offline angora  
#60 Оставлено : 24 февраля 2020 г. 10:31:44(UTC)
angora

Статус: Новичок

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

Сказал(а) «Спасибо»: 3 раз
Добрый день. Тоже бьемся с подписью XML. Проверка justsign.me говорит что подпись недействительна.
GetHashStream взят из приведенных выше примеров кода, разве что константы алгоритмов заменены на PROV_GOST_2012_256 (80) и ALG_SID_GR3411_2012_256 (33)

Далее куски кода взяты миксом из ранее приведенных в треде, и из предоставленного поставщиком услуги файла примера (который кстати проходит валидацию, разве что ругается что сертификат кривой):

SignedInfo := '<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">' +
'<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>' +
'<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"></SignatureMethod>' +
'<Reference URI="#body">' +
'<Transforms>' +
'<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>' +
'<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>' +
'</Transforms>' +
'<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"></DigestMethod>' +
'<DigestValue>' + TIdEncoderMIME.EncodeStream(Hash) + '</DigestValue>' +
'</Reference>'+
'</SignedInfo>';

CertId := 'SenderCertificate';

Security:= '<wsse:Security soap:actor="http://smev.gosuslugi.ru/actors/smev">' +
'<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ' +
'ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" ' +
'wsu:Id="' + CertId + '">' + TIdEncoderMIME.EncodeStream(Cert) +
'</wsse:BinarySecurityToken>' +
'<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">' +
SignedInfo +
'<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#">' + TIdEncoderMIME.EncodeStream(Sign) + '</SignatureValue>' +
'<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">' +
'<wsse:SecurityTokenReference>' +
'<wsse:Reference URI="#' + CertId + '" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>' +
'</wsse:SecurityTokenReference>' +
'</KeyInfo>'+
'</ds:Signature>'+
'</wsse:Security>';

// Собираем итоговый пакет
Result := '<?xml version="1.0" encoding="utf-8"?>' +
'<soap:Envelope xmlns:rar="http://fns.smev.fsrar.ru/serviceLicSA/rev111111" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" ' +
'xmlns:smev="http://smev.gosuslugi.ru/rev111111" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' +
'<soap:Header>' + Security + '</soap:Header>' +
BodyContext +
'</soap:Envelope>';

Судя по коду, с каноникализацией там не все гладко, но оригинальный-то файл проверку проходит !

Дайджест проверил, вроде результат как совпадает и с cpverify, и с vipnethashcalc
Есть у кого мысли, в чем дело может быть, где нестыковка ?

Отредактировано пользователем 24 февраля 2020 г. 14:35:12(UTC)  | Причина: Не указана

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