29 votes

SignedXml.CheckSignature échoue dans .NET 4 mais il fonctionne dans .NET 3.5, 3 ou 2

J'ai une réponse à partir d'un 3 ème partie du service web. Je charge un XmlDocument avec cette réponse.

  string txt = readStream.ReadToEnd();
  response = new XmlDocument();
  response.PreserveWhitespace = true;
  response.LoadXml(txt);   
  return response;

Maintenant, je voudrais vérifier que le respones est signé à l'aide du certificat. J'ai un VerifyXmlDoc(XmlDocument xmlDoc) méthode que j'ai trouvé sur msdn.

Je sais que le message est correct.

    public bool VerifyXmlDoc(XmlDocument xmlDoc)
    {

        SignedXml signed = new SignedXml(xmlDoc);

        XmlNodeList signatureNodeList = xmlDoc.GetElementsByTagName("Signature");


        signed.LoadXml((XmlElement)signatureNodeList[0]);

        X509Certificate2 serviceCertificate = null;
        foreach (KeyInfoClause clause in signed.KeyInfo)
        {
            if (clause is KeyInfoX509Data)
            {
                if (((KeyInfoX509Data)clause).Certificates.Count > 0)
                {
                    serviceCertificate = (X509Certificate2)((KeyInfoX509Data)clause).Certificates[0];
                }
            }
        }


        bool result = signed.CheckSignature(serviceCertificate, true);
        return result;

    }

Si j'ai mis cible cadre de mon projet de .NET 3.5 ou .NET 3, ou .NET 2, il fonctionne très bien. Le résultat est vrai. Mais si je change de cible cadre au .NET 4 résultat est faux. (Et je dois utiliser .NET 4)

Toutes les idées sur la façon de résoudre ce problème?

1voto

Onots Points 842

Essayez de définir explicitement la méthode Canonicalization pour la propriété SignedInfo de la classe SignedXml. Il semble qu'il y ait eu un changement de comportement par défaut ici entre .Net 2.0 et .Net 4.0

 signed.SignedInfo.CanonicalizationMethod = Signed.XmlDsigExcC14NTransformUrl;
 

Référence:

Cette réponse

0voto

user3531153 Points 1
// Assume the data to sign is in the data.xml file, load it, and

// set up the signature object.
XmlDocument doc = new XmlDocument();

doc.Load(@"D:\Example.xml");
SignedXml sig = new SignedXml(doc);

// Make a random RSA key, and set it on the signature for signing.
RSA key = new RSACryptoServiceProvider();

sig.SigningKey = key;

// Create a Reference to the containing document, add the enveloped
// transform, and then add the Reference to the signature
Reference refr = new Reference("");refr.AddTransform(new XmlDsigEnvelopedSignatureTransform());

sig.AddReference(refr);

// Compute the signature, add it to the XML document, and save
sig.ComputeSignature();

doc.DocumentElement.AppendChild(sig.GetXml());
doc.Save("data-signed.xml");

// Load the signed data

//XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;

doc.Load("data-signed.xml");

// Find the Signature element in the document
XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable());

nsm.AddNamespace("dsig", SignedXml.XmlDsigNamespaceUrl);
XmlElement sigElt = (XmlElement)doc.SelectSingleNode("//dsig:Signature", nsm);

// Load the signature for verification

//SignedXml sig = new SignedXml(doc);

sig.LoadXml(sigElt);

// Verify the signature, assume the public key part of the

// signing key is in the key variable
if (sig.CheckSignature(key))
    Console.WriteLine("Signature verified");
else
    Console.WriteLine("Signature not valid");

0voto

biswapm Points 15
public static Boolean VerifyDetachedSignature(string XmlSigFileName)
{   
    // Create a new XML document.
    XmlDocument xmlDocument = new XmlDocument();

    // Load the passed XML file into the document.
    xmlDocument.Load(XmlSigFileName);

    // Find the "Signature" node and create a new XmlNodeList object.
    XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");

    // Create a new SignedXMl object.
    SignedXml signedXml = new SignedXml();

    // Load the signature node.
    signedXml.LoadXml((XmlElement)nodeList[0]);

    // Check the signature and return the result. 
    return signedXml.CheckSignature();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X