Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

8 Страницы123>»
Опции
К последнему сообщению К первому непрочитанному
Offline slavw  
#1 Оставлено : 9 февраля 2015 г. 12:13:26(UTC)
slavw

Статус: Активный участник

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

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 22 раз в 12 постах
Тема создана с целью помочь тем, кто пишет на Delphi.
Первый шаг: это каноникализация XML. Без этого ничего не получится.
Средств у Delphi для этого нет (XE7), так что надо уметь создать XML в каноническом виде.
Это очень важно! Без этого НИКОГДА у вас не получится правильно подписать сообщение.
Я убил на это 2 недели, и только сегодня у меня получилось. Сразу скажу: подобрать
канонический вид так, как это делает СМЭВ вручную очень сложно.
После 2-х недель е***ни Brick wall я запустил VisualStudio и сделал программу для этого.
Программа требует установленного Framework 4.0 (а может и не требует).
программа во вложении...

Отредактировано пользователем 9 февраля 2015 г. 12:16:09(UTC)  | Причина: Не указана

Вложение(я):
c14n.zip (5kb) загружен 316 раз(а).

У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
thanks 5 пользователей поблагодарили slavw за этот пост.
vgs оставлено 20.03.2015(UTC), nikisha оставлено 03.08.2015(UTC), vladplus оставлено 14.01.2016(UTC), paveln оставлено 22.02.2018(UTC), Infopol оставлено 08.12.2022(UTC)
Offline MCR  
#2 Оставлено : 9 февраля 2015 г. 18:13:03(UTC)
MCR

Статус: Активный участник

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

Сказал(а) «Спасибо»: 57 раз
Поблагодарили: 11 раз в 8 постах
Автор: slavw Перейти к цитате

Средств у Delphi для этого нет (XE7)

Спорное утверждение. Делфи тут не причем.


Новичкам может больше помочь пример (исходник) для СМЭВ под делфи или пример вызова какого-нибудь метода.

Offline Андрей Писарев  
#3 Оставлено : 9 февраля 2015 г. 20:02:35(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2034 раз в 1578 постах
То, что в первом посте:
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
MCR оставлено 10.02.2015(UTC)
Offline slavw  
#4 Оставлено : 10 февраля 2015 г. 8:16:26(UTC)
slavw

Статус: Активный участник

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

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 22 раз в 12 постах
Я не утвержаю, что в Delphi нет средств для каноникализации XML... я констатирую этот факт. Если у кого то есть сомнения по этому поводу, что ж...
Можно написать и самому, но для этого надо знать как оно должно работать... именно с этой целью я и выложил программу c14n.exe... если вы не сможете вручную преобразовать XML к каноническому виду, то тем более не сможете "научить" этому свою процедуру...
А исходники конечно будут, если будет интерес к этому вопросу...
но не будет толка от процедур для получения хеша и подписи пока не будет возможности передать им "нужный" XML...
Offline MCR  
#5 Оставлено : 10 февраля 2015 г. 10:00:52(UTC)
MCR

Статус: Активный участник

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

Сказал(а) «Спасибо»: 57 раз
Поблагодарили: 11 раз в 8 постах
Автор: slavw Перейти к цитате
Я не утвержаю, что в Delphi нет средств для каноникализации XML... я констатирую этот факт. Если у кого то есть сомнения по этому поводу, что ж...
Можно написать и самому, но для этого надо знать как оно должно работать... именно с этой целью я и выложил программу c14n.exe... если вы не сможете вручную преобразовать XML к каноническому виду, то тем более не сможете "научить" этому свою процедуру...
А исходники конечно будут, если будет интерес к этому вопросу...
но не будет толка от процедур для получения хеша и подписи пока не будет возможности передать им "нужный" XML...


Интерес к вопросу есть.
Среди исходников могут быть примеры xml в виде файлов не канонизированного (исходный xml) и канонизированного xml (результат).

Libxml2 вы пробовали использовать для C14N XML canonicalization?
Offline slavw  
#6 Оставлено : 10 февраля 2015 г. 11:09:41(UTC)
slavw

Статус: Активный участник

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

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 22 раз в 12 постах
ok... я только рад помочь.. давайте, для начала, попробуем канонизировать вот такой простой вариант
(программой c14n.exe не пользоваться!... если вы не будете присылать свои варианты решения, я сам позже разберу этот пример, потом перейдем к примеру посложнее...):

<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
<ds:Reference URI="#body">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
<ds:DigestValue>acivl1p/l/aEtQoHJlkezFywapOcAipW90WvTnaac3A=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>

ps: и да! у любого xml должна быть единственная каноническая форма, без вариантов... смэв не будет выбирать как канонизировать xml для дальнейшей обработки... мы должны канонизировать его точно так же... до байта!!! только тогда подпись пройдет...

ладно... ответов нет. пишу сам:
1.канонализированный XML (далее буду писать C-XML) должен содержать все объявления пространства имен, который используются в тэгах и их атрибутах... в данном случае не обявлено что такое "ds"... добавим xmlns:ds="http://www.w3.org/2000/09/xmldsig#" в тэг <ds:SignedInfo>
2.не должно быть тегов вида <Tag/> они должны быть заменены на пары <Tag></Tag>

результат C-XML:

<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="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"></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="http://www.w3.org/2001/04/xmldsig-more#gostr3411"></ds:DigestMethod>
<ds:DigestValue>acivl1p/l/aEtQoHJlkezFywapOcAipW90WvTnaac3A=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>

Отредактировано пользователем 10 февраля 2015 г. 11:34:00(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил slavw за этот пост.
MCR оставлено 11.02.2015(UTC)
Offline slavw  
#7 Оставлено : 10 февраля 2015 г. 11:39:38(UTC)
slavw

Статус: Активный участник

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

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 22 раз в 12 постах
пример 2. сразу очень сложный пример, разобрав который, вы будете уметь составлять C-XML самостоятельно (ну почти...):

<ds4:Body ds5:id="ID001" xmlns:ds5="http:"
xmlns:ds1="http:" xmlns:ds2="http:"
xmlns:ds3="http:" xmlns:ds4="http:" xmlns:ds6="http:">
<ds1:Sender>
<ds2:Code>1226</ds2:Code>
<ds2:Name>Компания</ds2:Name>
<ds4:Code2>1228</ds4:Code2>
</ds1:Sender>
<ds5:Inner2/>
<ds3:Inner/>
<ds3:Autor/>
</ds4:Body>

ps: разбор примера через час...
thanks 1 пользователь поблагодарил slavw за этот пост.
MCR оставлено 11.02.2015(UTC)
Offline slavw  
#8 Оставлено : 10 февраля 2015 г. 12:03:50(UTC)
slavw

Статус: Активный участник

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

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 22 раз в 12 постах
пространства имен xmlns - основной геморрой...

1.все объявления пространств имен xmlns должны идти раньше чем атрибуты (ds5:id="ID001" надо перенести в "хвост" тэга <ds4:Body>)
2.и пр.имен и атрибуты должны быть упорядочены по алфавиту (xmlns:ds5 должен идти позже чем все остальные, которые останутся, xmlns:ds6 исчезнет совсем п.3)
3.не используемые в xml пр.имен должны быть удалены (xmlns:ds6="http:")
4.узлы одного уровня НЕ упорядочиваются по афавиту, а остаются на своих местах (<ds5:Inner2/> идет раньше чем <ds3:Inner/>... так и должно остаться)
5!!!!!.пр.имен должны быть объявлены только в тех узлах, в которых они используются (xmlns:ds1 не используется в <ds4:Body> должен быть опущен ниже, до <ds1:Sender>)

C-XML:

<ds4:Body xmlns:ds4="http:" xmlns:ds5="http:" ds5:id="ID001">
<ds1:Sender xmlns:ds1="http:"> ds1 нигде "выше" не используется
<ds2:Code xmlns:ds2="http:">1226</ds2:Code> ds2 нигде "выше" не используется
<ds2:Name xmlns:ds2="http:">Компания</ds2:Name> ds2 нигде "выше" не используется
<ds4:Code2>1228</ds4:Code2> а вот ds4 уже был обявлен ранее в родительском узле
</ds1:Sender>
<ds5:Inner2></ds5:Inner2> ds5 уже использовался (и объявлялся) ранее.. в <ds4:Body .... ds5:id="ID001">
<ds3:Inner xmlns:ds3="http:"></ds3:Inner> порядок тегов одного уровня не изменился!
<ds3:Autor xmlns:ds3="http:"></ds3:Autor> порядок тегов одного уровня не изменился!
</ds4:Body>


без примечаний:

<ds4:Body xmlns:ds4="http:" xmlns:ds5="http:" ds5:id="ID001">
<ds1:Sender xmlns:ds1="http:">
<ds2:Code xmlns:ds2="http:">1226</ds2:Code>
<ds2:Name xmlns:ds2="http:">Компания</ds2:Name>
<ds4:Code2>1228</ds4:Code2>
</ds1:Sender>
<ds5:Inner2></ds5:Inner2>
<ds3:Inner xmlns:ds3="http:"></ds3:Inner>
<ds3:Autor xmlns:ds3="http:"></ds3:Autor>
</ds4:Body>

Отредактировано пользователем 10 февраля 2015 г. 12:04:47(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил slavw за этот пост.
MCR оставлено 11.02.2015(UTC)
Offline slavw  
#9 Оставлено : 10 февраля 2015 г. 13:10:14(UTC)
slavw

Статус: Активный участник

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

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 22 раз в 12 постах
про двойные кавычки, лишние пробелы между элементами тегов, замена спец.символов я даже не говорю, это обязательно:
нельзя: <ds4:Body xmlns:ds4='http:' xmlns:ds5="http:" ds5:id="ID001">
надо: <ds4:Body xmlns:ds4="http:" xmlns:ds5="http:" ds5:id="ID001">

пробелы между тегами сохраняются!
</ds5:Inner2>#32#32#32#32#32<ds3:Inner> так и останется

символы переноса строк #13#10 должны быть заменены на #10

чтобы не допускать лишних ошибок лучше совсем не использовать отступов и пробелов перед тегами и переносов строк...

если для составления XML вы используете TStringList то TStringList.Text вернет String1#13#10String2#13#10String3#13#10String4 учтите это
C-XML в этом случае заменит код #13 на строку '&#xD;' String1&#xD;#10String2&#xD;#10String3&#xD;#10String4 - вот что получится

чтобы не допускать лишних ошибок лучше вместо TStringList использовать обычный string

составленный XML проверьте с помощью c14n.exe - это будет гарантия того, что все нормально...
thanks 1 пользователь поблагодарил slavw за этот пост.
MCR оставлено 11.02.2015(UTC)
Offline slavw  
#10 Оставлено : 10 февраля 2015 г. 13:19:28(UTC)
slavw

Статус: Активный участник

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

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 22 раз в 12 постах
готовый C-XML для вычисления хеша должен быть переведен в UTF-8

вот рабочий код вызова процедуры вычисления хеша и подписи у меня:



function SoapCreateMessage(CryptContainer: WideString; BodyContext: string): string;
var
DataStream: TStream;
Cert,Hash,Sign: TBytesStream;
SignedInfo,Security: string;
TimeStamp: string;
CertId,KeyId,STRId,SignID: string;
begin

//обертка данных сообщения блоком <Body>
BodyContext:=
'<soapenv:Body '+
'xmlns:soapenv="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">'+
'<smev:GISGMPTransferMsg xmlns:smev="http://roskazna.ru/gisgmp/02000000/SmevGISGMPService/">'+
BodyContext+
'</smev:GISGMPTransferMsg>'+
'</soapenv:Body>';

DataStream:=TStringStream.Create(BodyContext,TEncoding.UTF8);
Hash:=TBytesStream.Create;
try

//вычисление хеша блока <Body>
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="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411">'+
'</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="http://www.w3.org/2001/04/xmldsig-more#gostr3411">'+
'</ds:DigestMethod>'+
'<ds:DigestValue>'+
//хэш элемента <soapenv:Body> по алгоритму ГОСТ Р 34.11-94 в формате base64
StreamAsBase64(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);

TimeStamp:='';
CertId:='CertId-'+SoapGenID;
KeyId:='KeyId-'+SoapGenID;
STRId:='STRId-'+SoapGenID;
SignID:='SignID-'+SoapGenID;

Security:=
'<wsse:Security '+
'soapenv: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+'">'+
//сертификат в формате Base64
StreamAsBase64(Cert)+
'</wsse:BinarySecurityToken>'+
'<ds:Signature Id="'+SignID+'" '+
'xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'+
//вставим готовый блок <SignedInfo>
SignedInfo+
'<ds:SignatureValue>'+
//электронная подпись для <ds:SignedInfo> по алгоритму ГОСТ Р 34.11-2001 в формате base64
StreamAsBase64(Sign)+
'</ds:SignatureValue>'+
'<ds:KeyInfo Id="'+KeyId+'">'+
'<wsse:SecurityTokenReference wsu:Id="'+STRId+'">'+
'<wsse:Reference URI="#'+CertId+'" '+
'ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>'+
'</wsse:SecurityTokenReference>'+
'</ds:KeyInfo>'+
'</ds:Signature>'+
'</wsse:Security>';

//soap envelope
Result:=
'<?xml version="1.0"?>'+
'<soapenv:Envelope '+
'xmlns:inc="http://www.w3.org/2004/08/xop/include" '+
'xmlns:mes="http://roskazna.ru/gisgmp/xsd/116/Message" '+
'xmlns:mes1="http://roskazna.ru/gisgmp/xsd/116/MessageData" '+
'xmlns:rev="http://smev.gosuslugi.ru/rev120315" '+
'xmlns:smev="http://roskazna.ru/gisgmp/02000000/SmevGISGMPService/" '+
'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" '+
'xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" '+
'xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" '+
'xmlns:xd="http://www.w3.org/2000/09/xmldsig#">'+
'<soapenv:Header>'+
Security+
'</soapenv:Header>'+
BodyContext+
'</soapenv:Envelope>';

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

end;
thanks 1 пользователь поблагодарил slavw за этот пост.
MCR оставлено 11.02.2015(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
8 Страницы123>»
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.