powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как сделать Signature в XML файле?
14 сообщений из 39, страница 2 из 2
Как сделать Signature в XML файле?
    #38870152
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
меняю < на &lt
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870174
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman0888а нужно
<ds:Signature xmlns:ds=" http://www.w3.org/2000/09/xmldsig#" Id="1">
Вот в этом-то точно нет никакго смысла - расположение атрибутов в узле не влияет на данные, представляющие xml. Если это вдруг важно для принимающей стороны, то вырвать тем программистам ноги и голову. А вам уже не останется ничего, кроме XSLT, т.к. никакого контроля снаружи для формирования выходного дерева подписи API не предоставляет. Ну, или еще можно руками удалить атрибут Id, и добавить его снова - эмпирически он должен добавиться в конец списка атрибутов, т.е. после объявления неймспейса (но с т.з. теории такой гарантии нет - это отдано целиком на откуп парсеру, т.е. implementation-specific).
Roman0888Но когда я подписываю xml сам и заменяю "<" на "<" то сервер выдает ответ ошибка цифровой подписи.
1. Попробуйте всё-таки отослать подпись без префикса ds - как я уже писал в другой теме, в нем нет никакого особенного смысла.
2. Если уж без него никак - можно попробовать вот такой хак:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
public class PrefixedSignedXml : SignedXml
{
  public PrefixedSignedXml(XmlDocument document)
    : base(document){}
  public PrefixedSignedXml(XmlElement element)
    : base(element) { }

  public string SignaturePrefix { get; private set; }

  public void ComputeSignature(string signaturePrefix)
  {
    SignaturePrefix = signaturePrefix;
    BuildDigestedReferences();
    var key = SigningKey;
    if (key == null)
      throw new CryptographicException(GetSecurityResource("Cryptography_Xml_LoadKeyFailed"));
    if (SignedInfo.SignatureMethod == null)
    {
      if (key is DSA)
        SignedInfo.SignatureMethod = XmlDsigDSAUrl;
      else if (key is RSA)
      {
        if (SignedInfo.SignatureMethod == null)
          SignedInfo.SignatureMethod = XmlDsigRSASHA1Url;
      }
      else
        throw new CryptographicException(GetSecurityResource("Cryptography_Xml_CreatedKeyFailed"));
    }
    var signatureDescription = CryptoConfig.CreateFromName(SignedInfo.SignatureMethod) as SignatureDescription;
    if (signatureDescription == null)
      throw new CryptographicException(GetSecurityResource("Cryptography_Xml_SignatureDescriptionNotCreated"));
    var hashAlg = signatureDescription.CreateDigest();
    if (hashAlg == null)
      throw new CryptographicException(GetSecurityResource("Cryptography_Xml_CreateHashAlgorithmFailed"));
    GetC14NDigest(hashAlg);
    var asymmetricSignatureFormatter = signatureDescription.CreateFormatter(key);
    m_signature.SignatureValue = asymmetricSignatureFormatter.CreateSignature(hashAlg);
  }

  public new XmlElement GetXml()
  {
    var e = base.GetXml();
    SetPrefix(e);
    return e;
  }

  private void BuildDigestedReferences()
  {
    typeof(SignedXml).GetMethod("BuildDigestedReferences",
      BindingFlags.NonPublic | BindingFlags.Instance)
      .Invoke(this, new object[] { });
  }

  private byte[] GetC14NDigest(HashAlgorithm hash)
  {
    var document = new XmlDocument {PreserveWhitespace = true};
    var e = SignedInfo.GetXml();
    document.AppendChild(document.ImportNode(e, true));
    var canonicalizationMethodObject = SignedInfo.CanonicalizationMethodObject;
    SetPrefix(document.DocumentElement);
    canonicalizationMethodObject.LoadInput(document);
    return canonicalizationMethodObject.GetDigestedOutput(hash);
  }

  void SetPrefix(XmlNode node)
  {
    var nodes = node.SelectNodes(@"//descendant-or-self::*");
    if (nodes==null)
      throw new InvalidOperationException("Signature is empty.");
    nodes.Cast<XmlElement>()
      .ToList().ForEach(n => n.Prefix = SignaturePrefix);
  }

  private static readonly MethodInfo getSecurityResourcesMethod = typeof (SignedXml)
    .Assembly
    .GetType("System.Security.SecurityResources")
    .GetMethod("GetResourceString", BindingFlags.Static | BindingFlags.NonPublic);
  static string GetSecurityResource(string key)
  {
    return (string) getSecurityResourcesMethod.Invoke(null, new object[] {key});
  }
}


соответственно, использовать вот так:
Код: c#
1.
2.
3.
var sx = new PrefixedSignedXml(xd) { SigningKey = certificate.PrivateKey };
...
sx.ComputeSignature("ds");


но это уже на ваш страх и риск - нет никаких гарантий что в будущем в очередной версии фреймворка будет метод BuildDigestedReferences, вызываемый через рефлекшн, или что логика GetC14NDigest останется прежней, и т. п.
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870310
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Отлично! опробовал - расположение id на самом деле не имеет значения .
Разгадка близка))

1) Скажите при подписывании будет разница между "<" "&_lt;"

2) не могли бы вы изменить код так чтобы подписывалось только то что находится внутри <Data>

using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;

namespace test
{
class Program
{
static void Main()
{
const string quote = "\"";
SignXml(@"<Data>
<DC>
</DC>"
</Data>, Certificate, @"C:\24.xml");
var xd = new XmlDocument();
xd.Load(@"c:\24.xml");
var checker = new SignedXml(xd);
// сигнатура - последний дочерний элемент корня
var signature = (XmlElement)xd.SelectSingleNode("/*/*[last()]");
checker.LoadXml(signature);
var res = checker.CheckSignature(Certificate.PrivateKey);
Console.WriteLine(res);

Console.WriteLine(quote);
Console.ReadKey(true);
}

static X509Certificate2 Certificate
{
get
{
var cert = new X509Certificate2();
cert.Import("C:\\cert\\GOST.p12", "pass", X509KeyStorageFlags.MachineKeySet);
return cert;

}
}

static void SignXml(string content, X509Certificate2 certificate, string filePath)
{
var xd = new XmlDocument();
xd.LoadXml(content);
var sx = new SignedXml(xd) { SigningKey = certificate.PrivateKey };
sx.Signature.Id = "1";
var @ref = new Reference { Uri = string.Empty };
@ref.AddTransform(new XmlDsigEnvelopedSignatureTransform());
@ref.AddTransform(new XmlDsigC14NWithCommentsTransform());
sx.AddReference(@ref);
var keyInfo = new KeyInfo();
var keyData = new KeyInfoX509Data(certificate);
keyInfo.AddClause(keyData);
sx.KeyInfo = keyInfo;
sx.ComputeSignature();
var signature = sx.GetXml();
signature.AppendChild(xmlDoc.DocumentElement.ChildNodes[0]);[SRC C#][/SRC]
xd.DocumentElement.AppendChild(signature);
using (var fs = new FileStream(filePath, FileMode.Create))
using (var xw = XmlWriter.Create(fs, new XmlWriterSettings { Indent = true }))
xd.Save(xw);
}
}
}
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870375
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот еще момент : после добавлении строки - sx.Signature.Id = "1";
<DC> - до подписания
<Id xsi:nil="true"/>
.....
</DC>

после подписания становится вот так - хотя она должна остаться на своем месте
<DC>
......
<Signature Id="1" xmlns=" http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
....
</KeyInfo>
<Id xsi:nil="true" xmlns=" http://n.......edit" />
</Signature>
</DC>
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870945
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman0888меняю < на <
Roman08881) Скажите при подписывании будет разница между "<" "&_lt;"
Это еще зачем? Приведите более-менее подробные примеры исходного XML, и подписанного в том виде, в котором его предоставляет стороняя программа. Каждый пример заключите в тэг [SRС XML] - внутри него XML entities не преобразуются в символы:
Код: xml
1.
2.
3.
&lt;MyXML xmlns="Don't_Sign"&gt;
	&lt;TempElement xmlns="Sign"&gt;Here is some data to sign.&lt;/TempElement&gt;
&lt;/MyXML&gt;


Roman08882) не могли бы вы изменить код так чтобы подписывалось только то что находится внутри <Data>
Не могу. Точнее, могу, но без префикса ds - c этим префиксом вышеприведенный хак не работает для случая подписания узла внутри документа (подпись не проходит проверку), он работает только для документа целиком. Можно утверждать, что средствами .NET FCL невозможно сделать подпись с префиксом неймспейса - по крайней мере, гугл не предлагает ничего другого, кроме того, что я привел выше.

И используйте тэг [src] - невозможно же читать код в таком виде, как у вас.
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870952
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вообщем мне нужно подписать то что внутри <Data>......</Data>, это вложенный документ. Т.е я отправляю soap запрос внутри которого подписанный xml. внутри Data - должен находится тот самый подписанный xml

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
[/SRC]  
<Data>&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;DC xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2" xmlns="http://nitec.kz/mtc/ins/diagnosticCard/edit"&gt;
&lt;Id xsi:nil="true"/&gt;&lt;LastId&gt;5&lt;/LastId&gt;
&lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="1">
&lt;ds:SignedInfo&gt;
&lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/&gt;&lt;
ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha1"/&gt;
&lt;ds:Reference URI=""&gt;
&lt;ds:Transforms&gt;
&lt;ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/&gt;
&lt;ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/&gt;&lt;/ds:Transforms&gt;
&lt;ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha1"/&gt;
&lt;ds:DigestValue&gt;dR7...E=&lt;/ds:DigestValue&gt;
&lt;/ds:Reference&gt;
&lt;/ds:SignedInfo&gt;
&lt;ds:SignatureValue&gt;VaL...=&lt;/ds:SignatureValue&gt;
&lt;ds:KeyInfo&gt;
&lt;ds:X509Data&gt;
&lt;ds:X509Certificate&gt;MIIIE....G&lt;/ds:X509Certificate&gt;
&lt;/ds:X509Data&gt;
&lt;/ds:KeyInfo&gt;
&lt;/ds:Signature&gt;
&lt;/DC&gt;
</Data>
[SRC HTML]



можно попробовать без тега DS:

я использовал ваш исходник , с вашей помощью изменил , но он подписывает вместе с <Data>
а если начинаю с
Код: xml
1.
&lt;DC&gt;

ошибку про символы
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870955
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman0888а если начинаю с
Код: xml
1.
&lt;DC&gt;

ошибку про символы
Потому что это уже не XML, а обычный текст, и средствами System.Security.Cryptography.Xml вы это не подпишете никак. Либо помещайте ваш XML без XML declaration внутрь Data как дочерний узел, либо внутри Data создавайте CDATA-секцию, и подписывайте узел, содержащий эту секцию.
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870956
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В примере не весь документ , а часть его.

Еще я заметил если я меняю расположение строк в xml файле сделанный другой программой, и подставляю в свою, то тоже выдает ошибку не верная подпись, может из за этого моя тоже не проходить?
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870958
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вот код которым я подписываю

хотелось бы подписать то что внутри DATA при этом Uri ="" осталось бы пустым



using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;

namespace test
{
class Program
{
static void Main()
{
const string quote = "\"";
SignXml(@"<Data><DC xmlns:xsi=" + quote + " http://www.w3.org/2001/XMLSchema-instance" + quote + " xmlns:xsd=" + quote + " http://www.w3.org/2001/XMLSchema" + quote + " version=" + quote + "2" + quote + " xmlns=" + quote + " http://........it" + quote + "><Id xsi:nil=" + quote + "true" + quote + "/><LastId>5</LastId>
....
</DC></Data>", Certificate, @"C:\1.xml");
var xd = new XmlDocument();
xd.Load(@"C:\1.xml");
var checker = new SignedXml(xd);
// сигнатура - последний дочерний элемент корня
var signature = (XmlElement)xd.SelectSingleNode("/*/*[last()]");
checker.LoadXml(signature);
var res = checker.CheckSignature(Certificate.PrivateKey);
Console.WriteLine(res);
Console.ReadKey(true);
}

static X509Certificate2 Certificate
{
get
{
var cert = new X509Certificate2();
cert.Import("C:\\cert\\GOST.p12", "pass", X509KeyStorageFlags.MachineKeySet);
return cert;
}
}

static void SignXml(string content, X509Certificate2 certificate, string filePath)
{
var xd = new XmlDocument();
xd.LoadXml(content);
var sx = new SignedXml(xd) { SigningKey = certificate.PrivateKey };
sx.Signature.Id = "1";
var @ref = new Reference { Uri = string.Empty };
@ref.AddTransform(new XmlDsigEnvelopedSignatureTransform());
@ref.AddTransform(new XmlDsigC14NWithCommentsTransform());
sx.AddReference(@ref);
var keyInfo = new KeyInfo();
var keyData = new KeyInfoX509Data(certificate);
keyInfo.AddClause(keyData);
sx.KeyInfo = keyInfo;
sx.ComputeSignature();
var signature = sx.GetXml();
// сигнатура будет последним дочерним элементом корня
xd.DocumentElement.AppendChild(signature);
using (var fs = new FileStream(filePath, FileMode.Create))
using (var xw = XmlWriter.Create(fs, new XmlWriterSettings { Indent = true }))
xd.Save(xw);
}
}
}
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870961
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сон Веры Павловны, Говоря про xml без XML declaration вы имеет ввиду
Код: xml
1.
&lt;?xml version="1.0" encoding="utf-16"?&gt;
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38870968
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman0888, Если я вас правильно понял, то мне эта строчка там не нужна,я просто в своем запросе сделаю так:

я проверил так уходит

<Request>_
<Login>...</Login>
<Password>....</Password>
<Data><?xml version=" & Chr(34) & "1.0" & Chr(34) & " encoding=" & Chr(34) & "utf-16" & Chr(34) & "?>
....
(тут подписанный xml)
......
</Data>
</Request>
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38871231
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в общем после множества испытаний я пришел вот к чему спасибо за это Сон веры Павловны

1)вместо того чтобы писать
Код: xml
1.
&lt; 

можно сделать [CDATA[ .... это на самом деле проще и лучше.

2)Внутри [CDATA[ не нужно вот это <?xml version="1.0" encoding="utf-8"?>

теперь по запросу. я отправляю так
"<Request><Login>...</Login><Password>....</Password><Data><![CDATA[" & line & "]]></Data>" где line - нужный мне подписанный xml. Если я вставляю в line xml сгенирированный сторонней программой которsq выглядит так, предварительно ручками заменив
Код: xml
1.
&lt; на "<" и &gt; на ">"  

ВСЕ ОПРАВЛЯЕТСЯ БЕЗ ПРОБЛЕМ
А если же я подписываю сам то получается вот что
<DCxmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=" http://www.w3.org/2001/XMLSchema" version="2" xmlns=" http://....it">
<Id xsi:nil="true" />
<LastId>6845195</LastId>
.........
<Signature Id="1" xmlns=" http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm=" http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm=" http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="">
<Transforms>
<Transform Algorithm=" http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm=" http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" />
</Transforms>
<DigestMethod Algorithm=" http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>R....M=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>Kxe......n50jzxnqQ==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MII.........nOfIxO3q/bG</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</DC>

Выдает "Ошибку Подписи XML

Скажите Может дело в том , что не в одну строчку записан мною подписанный XML
или еще заметил вот что -
Код: xml
1.
 в моем xml  <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> в конце между sha1" и / , есть пробел, а сделанной в другой программе нет         


для подписания использую код в спойлере выше
Подскажите пожалуйста, как решить (осталось только подписать документ и моя программа готова)
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38871276
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поискав в интернете нашел вот еще кое что
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
Dim Doc As New XmlDocument
        Doc.PreserveWhitespace = True
        Dim sr As New System.IO.StreamReader("0001_send.xml")
        Doc.Load("24.xml")
       Dim cert As New X509Certificate2
        cert.Import("C:\cert\GOST.p12", "11111", X509KeyStorageFlags.MachineKeySet)
        Dim MSCert As X509Certificate2 = cert 'GetCertificateBySubject(conf_Cer)
        Dim signedXml As New SignedXml(Doc)
        signedXml.Signature.Id = "1"
        signedXml.SigningKey = MSCert.PrivateKey
        Dim reference As New Reference()
        reference.Uri = ""
        Dim trns As XmlDsigC14NTransform = New XmlDsigC14NTransform()
        reference.AddTransform(trns)

       Dim env As New XmlDsigEnvelopedSignatureTransform()
        reference.AddTransform(env)
        signedXml.AddReference(reference)

        Dim keyInfo As New KeyInfo()

        keyInfo.AddClause(New KeyInfoX509Data(MSCert))
        signedXml.KeyInfo = keyInfo
        signedXml.ComputeSignature()
        Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
        Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, True))
        Doc.Save("5556.xml")



после выполнения получил одинаковые <DigestValue> и <X509Certificate> , но совершенно разные <SignatureValue> ,с моей предыдущей подписью сделанной в test
...
Рейтинг: 0 / 0
Как сделать Signature в XML файле?
    #38871511
Roman0888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сон Веры Павловны, не подскажите как в предыдущем ранее коде на c# сделать так , чтобы после подписания xml в одну строку был записан?
Все таки мне кажется , что ошибка как раз из за этого (потому что если я меняю в xml сделанный в стор.программе расположение строчки, то выходит аналогичная ошибка)
...
Рейтинг: 0 / 0
14 сообщений из 39, страница 2 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как сделать Signature в XML файле?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]