Проблемы с проверкой подписи XML с помощью XmlDsigExcC14NTransform и InclusiveNamespaces

У меня есть XML-документ, в котором мне нужно проверить подпись. Элемент SignedInfo имеет элемент CanonicalizationMethod, который определяет алгоритм "http://www.w3.org/2001/10/xml-exc-c14n#", а также имеет дочерний элемент InclusiveNamespaces с заполненным атрибутом PrefixList, например:

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <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="soapenv"></ec:InclusiveNamespaces>
  </ds:CanonicalizationMethod>...

Я использую следующий код для создания своего объекта C14Transform:

XmlDsigExcC14NTransform cn14Transform = new XmlDsigExcC14NTransform(false, "soapenv");

где "soapenv" происходит от атрибута PrefixList.

При канонизации приведенного выше XML (игнорируя пробелы) он должен выглядеть так (обратите внимание на часть xmlns:soapenv="..." в строке 2):

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
        xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<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="soapenv"></ec:InclusiveNamespaces>
</ds:CanonicalizationMethod>
...

У меня проблема в том, что часть xmlns:soapenv="..." не включается при канонизации, что приводит к сбою проверки подписи.

Я могу обойти это, вставив его программно, но это проблема, так как будут вариации содержимого PrefixList.


person elSeten    schedule 18.06.2015    source источник
comment
Я сомневаюсь, что вы можете многое сделать. Где он волшебным образом выведет uri для объявления пространства имен, которое он должен добавить? Разве оригинал не должен иметь этот атрибут, если он требуется для проверки подписи?   -  person Charles Mager    schedule 18.06.2015
comment
Объявление пространства имен уже существует в XML-документе, просто где-то еще. Я надеялся, что в объекте преобразования есть какая-то настройка, которую мне нужно было включить, чтобы каноническая версия вышла правильной. У меня есть подтверждение, что это правильно работает на других языках, по крайней мере, на php. Кроме того, InclusiveNamespaces является частью стандарта Exclusive Canonicalization W3C, поэтому я предполагаю, что Microsoft покрывает его.   -  person elSeten    schedule 18.06.2015


Ответы (1)


Возможно, вам поможет эта почтовая форма Microsoft: https://support.microsoft.com/en-us/kb/2639079

Они показывают вам, как зарегистрировать пользовательское преобразование для алгоритма канонизации. Он используется для удаления пространства имен, но я думаю, вы также можете использовать его для добавления.

public class  MyXmlDsigExcC14NTransform : XmlDsigExcC14NTransform 
{ 
   public MyXmlDsigExcC14NTransform() {} 

   public override  void LoadInput(Object obj) 
   {            
      XmlElement root = ((XmlDocument)obj).DocumentElement; 
      if (root.Name == "SignedInfo") root.RemoveAttribute("xml:id");            
      base.LoadInput(obj);                      
   } 
}

В начале вашего приложения MyXmlDsigExcC14NTransform можно зарегистрировать с помощью следующего вызова:

CryptoConfig.AddAlgorithm(typeof(MyXmlDsigExcC14NTransform), "http://www.w3.org/2001/10/xml-exc-c14n#"); 
person Patrick Koorevaar    schedule 21.07.2015
comment
Эй, спасибо за это. Это чище, чем то, что я сейчас делаю, однако я все еще тайно надеялся, что библиотека Microsoft будет правильно обрабатывать префиксные списки. - person elSeten; 23.07.2015