SignedXml no controla correctamente los atributos de espacio de nombres xml


Síntomas


No se puede comprobar una firma xml como situado debajo de la clase SignedXml.

<tns:CertificateStatusResponse xmlns="" xmlns:dpfunc="http://www.datapower.com/extensions/functions" xml:id="response">
<tns:ReturnCode>00</tns:ReturnCode>
<tns:ReturnText>OK</tns:ReturnText>
<tns:CertificateStatus>
  <tns:CertificateSerialNo>3419000000001401</tns:CertificateSerialNo>
  <tns:CertificateType>signing</tns:CertificateType>
  <tns:MatchingCertificateSerialNo>3419000000001402</tns:MatchingCertificateSerialNo>
  <tns:Status><tns:revoked revocationDate="2011-01-21T10:12:04Z" CRLReason="1"/></tns:Status>
</tns:CertificateStatus>
<tns:Timestamp>2011-02-02T14:53:47Z</tns:Timestamp>
<tns:RequestId>hls=</tns:RequestId>
< firma xmlns = "http://www.w3.org/2000/09/xmldsig#" >
<SignedInfo>
< CanonicalizationMethod algoritmo = "http://www.w3.org/2001/10/xml-exc-c14n#" />
< SignatureMethod algoritmo = "http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
< referencia URI = "#response" >
    <Transforms>
< transform algoritmo = "http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
< transform algoritmo = "http://www.w3.org/2001/10/xml-exc-c14n#" />
    </Transforms>
< DigestMethod algoritmo = "http://www.w3.org/2000/09/xmldsig#sha1" />
    <DigestValue>4hTmTRbInGChuyeqoRs06Tug30s=</DigestValue>
  </Reference>
</SignedInfo>
<SignatureValue>jHG4+lRvqs1g8ZRLCdND7lT7qFQr6YnzQ...</SignatureValue>
<KeyInfo>
 <X509Data>
   <X509Certificate>MIIEADCCAuigAwIBAgIFAMa3vBEwDQYJKoZIhvcNAQELB...</X509Certificate>
  </X509Data>
</KeyInfo>
</Signature>
</tns:CertificateStatusResponse>

Causa


Cuando SignedXml.CheckSignature() intenta comprobar la firma canoniza el nodo SignedInfo y hereda incorrectamente los atributos de espacio de nombres xml. En este caso se hereda xml:id hasta SignedInfo que no debería ocurrir e invalida la firma.

Solución


En .NET 4.0, esto se puede solucionar registrando una transformación personalizada para el algoritmo de canonización. La transformación personalizada delega a la transformación de la Exc14N integrada y quita el atributo de espacio de nombres xml.

La clase de transformación personalizada es muy corto y sencillo.
clase pública MyXmlDsigExcC14NTransform: XmlDsigExcC14NTransform
{
{} de MyXmlDsigExcC14NTransform() pública

public void LoadInput(Object obj) de reemplazar
   {           
Raíz de XmlElement = ((XmlDocument) obj). DocumentElement;
Si (raíz. Nombre == "SignedInfo") raíz. RemoveAttribute("xml:id");
base. LoadInput(obj);
   }
}

Al principio de la aplicación se puede registrar MyXmlDsigExcC14NTransform con la siguiente llamada:
CryptoConfig.AddAlgorithm(typeof(MyXmlDsigExcC14NTransform), "http://www.w3.org/2001/10/xml-exc-c14n#");

Cuando se llama a SignedXml.CheckSignature(), se llama MyXmlDsigExcC14NTransform para realizar la resolución de nombres canónicos que elimina el atributo xml:id.