Я пытаюсь создать клиент веб-службы SOAP.В какой-то момент в коде я должен вычислить хэш, чтобы подписать мой запрос.
Когда я пытаюсь канонизировать (используя xml-exc-c14n) тело моего запроса, у меня возникает исключение "Неопределенный префикс пространства имен ''".Пространство имен 's' определено в теге Envelope, поэтому я попытался иметь теги envelope и удалить их после канонизации.Это сработало, но когда я хеширую канонизированное тело, значение не совпадает со значением, вычисленным с помощью SoapUI (что правильно).
Может кто-нибудь сказать мне, почему хеш, сгенерированный в моем коде, отличается от хеша, сгенерированного SoapUI?
Я попытался изменить кодировку потока в методе CalculateHash, который изменил значение хеш-функции, но он все еще не соответствует SoapUI.
Метод, используемый для канонизации тега body:
public static string GetCanonicalXMLC14NForm(string monXML)
{
var envelope = string.Format("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\">{0}</s:Envelope>", monXML);
XmlDocument doc = new XmlDocument();
doc.LoadXml(envelope);
XmlDsigExcC14NTransform xmlTransform = new XmlDsigExcC14NTransform(true);
xmlTransform.InclusiveNamespacesPrefixList = "";
// Ensure the transform is using the appropriate algorithm.
xmlTransform.Algorithm = "http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718";
xmlTransform.LoadInput(doc);
// Retrieve the XML representation of the current transform.
MemoryStream outputStream = (MemoryStream)xmlTransform.GetOutput(typeof(Stream));
outputStream.Position = 0;
var sr = new StreamReader(outputStream);
var myStr = sr.ReadToEnd().Replace("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\">", "").Replace("</s:Envelope>", "");
return myStr;
}
Метод, используемый для вычисления хэша из канонизированного тела:
public static byte[] CalculateHash(string monXmlCanonise, X509Certificate2 certificate)
{
HashAlgorithm hashAlgo = HashAlgorithm.Create(GetHashAlgoFromCertificate(certificate));
// Pour calculer le hash, on a besoin d'un stream
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(monXmlCanonise);
writer.Flush();
stream.Position = 0;
// Cacluer le hash à partir du stream du xml canonisé
return hashAlgo.ComputeHash(stream);
}
Код, вызывающий методы:
var canonizedBody = GetCanonicalXMLC14NForm(_body);
var hash = CalculateHash(canonizedBody , myCertif);
Пример запроса SOAP:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<wsse:Security 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" s:mustUnderstand="true">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-6">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="cen s" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id-5">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="cen" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>mALggIhdtKIXoWyCYhSOusfxrhIDDOoMrDa7fdzhthQ=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>GQdkT9yyxBJ0fOQMsFvhIex9IMCCxEoR1LO28F6Q2XP59/qddd8JIHXsHGBfZUcaAUCvRNOGnwnhlfAgs5RoL6m2VGNhBGo24Tu3tBjEQJdL1X1xzK9+pHM67Bgc2OekXviNRrlv97NSRNPpDVAhDEriF7Mq5Pa9oz88OshnxCzyhXTjKIhDUfcPTfN9x+NX1EfBfcgFhkIa8gaz9QP2am6n9NKlAgnDI8AruWkqaMiQLZvPCLqYVOSkTKobd4xGVVd+Wr7aomEiZ0LtQREstgiH+dLMr+DHMSniWDdRzP/iINLjXfuFnG9+MV+o943MuMkzodsyMp/Di/xXzPOtbg==</ds:SignatureValue>
<ds:KeyInfo Id="KI-96940D73D32987C15214870649588808">
<wsse:SecurityTokenReference wsu:ID="STR-96940D73D32987C15214870649588809">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>...</ds:X509IssuerName>
<ds:X509SerialNumber>...</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</s:Header>
<s:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-5">...</s:Body>