2015-11-13 5 views
1

Мне нужно реализовать EBICS протокол, Particulary просьбе HPB и я должен подписать мой XML-файл:Некорректное опорный элемент подписи XML C#

<?xml version="1.0" encoding="UTF-8"?> 
<ebicsNoPubKeyDigestsRequest xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebics.org/H003 http://www.ebics.org/H003/ebics_keymgmt_request.xsd" Version="H003" Revision="1"> 
    <header authenticate="true"> 
    <static> 
     <HostID>EBIXQUAL</HostID> 
     <Nonce>234AB2340FD2C23035764578FF3091C1</Nonce> 
     <Timestamp>2015-11-13T10:32:30.123Z</Timestamp> 
     <PartnerID>AD598</PartnerID> 
     <UserID>EF056</UserID> 
     <OrderDetails> 
     <OrderType>HPB</OrderType> 
     <OrderAttribute>DZHNN</OrderAttribute> 
     </OrderDetails> 
     <SecurityMedium>0000</SecurityMedium> 
    </static> 
    <mutable /> 
    </header> 
</ebicsNoPubKeyDigestsRequest> 

Поэтому мне нужно подписать элементы, где

Аутентифицировать = "истинный"

Чтобы подписать мой документ в C# я писал этот код:

XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.PreserveWhitespace = false; 
     xmlDoc.Load("hpbtest.xml"); 
     RSA Key = new GestionCertificat("CN=XML_ENC_TEST_CERT4").getClePrivee(); 
     // Create a SignedXml object. 
     SignedXml signedXml = new SignedXml(xmlDoc); 
     // Add the key to the SignedXml document. 
     signedXml.SigningKey = Key; 
     // Create a reference to be signed. 
     Reference reference = new Reference(); 
     reference.Uri = "#xpointer(//*[@authenticate='true'])"; 
     // Add an enveloped transformation to the reference. 
     XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform(); 
     reference.AddTransform(env); 
     // Add the reference to the SignedXml object. 
     signedXml.AddReference(reference); 
     // Compute the signature. 
     signedXml.ComputeSignature(); 
     // Get the XML representation of the signature and save 
     // it to an XmlElement object. 
     XmlElement xmlDigitalSignature = signedXml.GetXml(); 
     // Append the element to the XML document. 
     xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); 
     xmlDoc.Save("hpbtest.xml"); 

Но когда я пытаюсь подписать его, я получаю эту ошибку на линии

signedXml.ComputeSignature()

:

Неверная ссылка элемент

Не могли бы вы помочь мне решить мою проблему se?

Спасибо заранее!

Thomas!

ответ

1

Я декомпиляции операции XPointer по SignedXml и ссылочных классов и .. я могу дать вам все детали в отдельном ответе, но то, что я завершаю сейчас есть, вы можете иметь только два типа запросов:

#xpointer(/) 

Это работает, потому что это явно проверяется на, и

#xpointer(id(

Это опять-таки явно (с string.StartsWith) проверил.

Таким образом, единственный путь для достижения этой цели, как вы указали в своем комментарии, кажется, хотел бы расширить класс SignedXml и переопределить метод GetIdElement следующим образом:

public class CustomSignedXml : SignedXml 
{ 
    XmlDocument xmlDocumentToSign; 

    public CustomSignedXml(XmlDocument xmlDocument) : base(xmlDocument) 
    { 
     xmlDocumentToSign = xmlDocument; 
    } 

    public override XmlElement GetIdElement(XmlDocument document, string idValue) 
    { 
     XmlElement matchingElement = null; 
     try 
     { 
      matchingElement = base.GetIdElement(document, idValue); 
     } 
     catch (Exception idElementException) 
     { 
      Trace.TraceError(idElementException.ToString()); 
     } 

     if (matchingElement == null) 
     { 
      // at this point, idValue = xpointer(//*[@authenticate='true']) 
      string customXPath = idValue.TrimEnd(')'); 
      customXPath = customXPath.Substring(customXPath.IndexOf('(') + 1); 
      matchingElement = xmlDocumentToSign.SelectSingleNode(customXPath) as XmlElement; 
     } 

     return matchingElement; 
    } 
} 

Затем в потребительском коде, просто изменить SignedXml к CustomSignedXml:

CustomSignedXml signedXml = new CustomSignedXml(xmlDoc); 
+0

протокол Ebics не принимает идентификатор атрибута в элементе заголовка, так что я не могу использовать ваше решение –

+0

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

+0

Как вы думаете, я могу переопределить 'GetIdElement' для выбора хороших узлов с помощью' #xpointer (// * [@ authenticate = 'true')] '? Но я не знаю, где я могу это сделать –

Смежные вопросы