none
Signature électronique ? RRS feed

  • Question

  • Bonjour à tous;

    je cherche à ajouter un préfixe et un espace de nommage pour ma signature 

    générée par la classe SignedXML.

     

    Le code que j'ai trouvé sur MSDN pour la signature :

    public static void SignXmlFile(string FileName, string filePDF,string SignedFileName, string[] ElementsToSign)

        {

            // Check the arguments.  

            if (FileName == null)

                throw new ArgumentNullException("FileName");

            if (SignedFileName == null)

                throw new ArgumentNullException("SignedFileName");

            if (ElementsToSign == null)

                throw new ArgumentNullException("ElementsToSign");

     

            // Create a new XML document.

            XmlDocument doc = new XmlDocument();

            doc.Load(FileName);

            // Format the document to ignore white spaces.

            doc.PreserveWhitespace = true;

            // Load the passed XML file using it's name.

            XmlNamespaceManager nsmanager;

            XmlNodeList messages;

            using (XmlTextReader reader = new XmlTextReader(FileName))

            {

                nsmanager = new XmlNamespaceManager(reader.NameTable);

                nsmanager.AddNamespace("eanucc", "urn:ean.ucc:2");

     

                XmlElement element = doc.DocumentElement;

                //Récuperer l'élément message

                messages = element.SelectNodes("eanucc:message", nsmanager);

                foreach (XmlNode message in messages)

                    element.RemoveChild(message);//Enlever l'élément message 

            }

            // Format the document to ignore white spaces.

            doc.PreserveWhitespace = false;

            // Create a SignedXml object.

            SignedXml signedXml = new XadesXml(doc);

            // Add the key to the SignedXml document. 

            signedXml.SigningKey = cryptor.Certificate.PrivateKey;

            // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).

            KeyInfo keyInfo = new KeyInfo();

            keyInfo.Id = "KeyInfo";

            keyInfo.AddClause(new KeyInfoX509Data(cryptor.Certificate));

            signedXml.KeyInfo = keyInfo;

            // DataObject SignedPropertiesId

            signedXml.AddObject(CreateDataObject());

            // Création de l'élément XML contenant les données à signer

            XmlElement root = doc.CreateElement("Content", SignedXml.XmlDsigNamespaceUrl);

            root.InnerText = Convert.ToBase64String(File.ReadAllBytes(filePDF));

            // DataObject GS1_PDF

            XmlElement obj = doc.CreateElement("ds", "Object", "http://www.w3.org/2000/09/xmldsig#");

            DataObject dataObject = new DataObject("GS1_PDF", null, null, obj);

            dataObject.Data = root.ChildNodes;

            signedXml.AddObject(dataObject);

            // DataObject GS1_XML

            DataObject dataObjectMsg = new DataObject("GS1_XML", null, null, obj);

            dataObjectMsg.Data = messages;

            signedXml.AddObject(dataObjectMsg);

     

            // Loop through each passed element to sign 

            // and create a reference.

            foreach (string s in ElementsToSign)

            {

                // Create a reference to be signed.

                Reference reference = new Reference();

                reference.Uri = s;

                if (s == "#SignedPropertiesId") reference.Type = "http://uri.etsi.org/01903/v1.3.2#SignedProperties";

                signedXml.AddReference(reference);

            }

            try

            {

                // Compute the signature.

                signedXml.ComputeSignature();

            }

            catch (CryptographicException e)

            {

                Console.WriteLine(e.Message);

            }

            catch (Exception e)

            {

                Console.WriteLine(e.Message);

            }

            // 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.

            doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

            // Save the signed XML document to a file specified

            // using the passed string.

            XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));

            doc.WriteTo(xmltw);

            xmltw.Close();

        }

     

    Merci d'avance pour votre réponse !

    vendredi 11 juin 2010 13:55

Toutes les réponses

  • Bonjour,

     

    Je vous propose ce thread qui traite le même problème. Apparemment, on peut mettre le préfix par programmation, mais cette modification va générer des erreurs si l’élément Signature est inclus dans le contenu signé.

    http://stackoverflow.com/questions/381517/net-signed-xml-prefix

     

    Cordialement,

    Alex

    __________________________________________________________________________________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Workflow Foundation

     

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

    mardi 15 juin 2010 11:34
  • En faite la modification de l'élément Signature de la classe SignedXML ne peut pas être faite après génération de la signature sinon la vérification sera non valide.

    J'ai échangé quelques messages avec Mr David Grellety auteur de l'article http://stormimon.developpez.com/dotnet/signature-electronique/ 

    Pour l'ajout du préfixe au niveau de la signature apparemment ce n'est pas possible sur la classe SignedXML , mais de toute façon les deux formes de la signature (avec ou sans préfixe) sont équivalentes.

    //

    Toujours sans réponse ?

     

    • Modifié edib27 jeudi 17 juin 2010 08:37
    mercredi 16 juin 2010 08:39
  • Bonjour,

     

    De mes recherches et à partir des informations que vous venez d’apporter, on est d’accord que la modification du xml après la génération de la signature va générer une erreur de vérification. L’impossibilité d’ajouter un préfixe vient de la conception de la classe SignedXML et pour le moment je ne connais aucun contournement pour ce problème.

     

    Cordialement,

    Alex

    __________________________________________________________________________________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Workflow Foundation

     

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

    mercredi 16 juin 2010 08:46
  • Bonjour ,

    Maintenant j'ai un souci au niveau de la vérification de la signature (sans ajout de préfixe).

    La vérification est invalide si j'ajoute une référence sur l'objet qui englobe le format Xades.

    La vérification est valide si j'omets  la référence sur l'objet qui englobe le format Xades.

    Avez vous une solution (piste) sur la non validation de la signature ?

    Très cordialement,

    Dib

    mercredi 16 juin 2010 09:11
  • Bonjour,

     

    C’est vraiment bizarre et je ne connais pas la cause. Essayez de comparer le contenu de l’objet avec et sans référence, pur voir s’il s’agit d’une modification qui nous échappe.

     

    Cordialement,

    Alex

    __________________________________________________________________________________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Workflow Foundation

    Boire un café virtuel et discuter: Café des usages

     

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     

    jeudi 17 juin 2010 10:39
  • Bonjour,

     

    Oui tout à fait bizarre,  depuis quelque temps je me balade de forum en forum mais sans grand résultat.

    Voilà mon code : 

     

     

    public class SignEnveloping

    {

        static X509Certificate2 _certificate = null;

        public static void Main(String[] args)

        {

            string directoryGS1 = @"C:\Documents and Settings\adib\Bureau\xml\GS1-XML_light\";

            string directoryPDF =@"C:\Documents and Settings\adib\Bureau\pdfA1-GS1Light\";

            try

            {

                // Specify an element to sign. , "#SignedPropertiesId" 

                string[] elements = { "#GS1_PDF", "#GS1_XML", "#SignedPropertiesId" };

                // Sign an XML file and save the signature to a 

                // new file.

                foreach (string FileGS1 in Directory.GetFiles(directoryGS1))

                {

                    string FilePDF = directoryPDF + "" + Path.GetFileName(FileGS1).Replace("_new corrige GM_GS1Light.xml", ".pdf");

                    string Signature = directoryPDF + "" + Path.GetFileName(FileGS1).Replace("_new corrige GM_GS1Light.xml", "_Enveloping.xml");

                    SignXmlFile(FileGS1,FilePDF,Signature,elements);

                    Console.WriteLine("XML and PDF files signed.");

                    if(VerifyXmlSignature(Signature))

                        Console.WriteLine("The XML signature is valid.");

                    else

                        Console.WriteLine("The XML signature is not valid.");

                    Console.WriteLine("-------------------------------");

                }

            }

            catch (CryptographicException e) { Console.WriteLine(e.Message); }

            finally {   Console.ReadLine(); }

        }

     

        //Choose Certificate in store

        private static X509Certificate2 GetCertificate()

        {

            X509Store store = new X509Store(StoreLocation.CurrentUser);

            store.Open(OpenFlags.ReadOnly);

            foreach (X509Certificate2 cert in store.Certificates)

            {

                if (cert.Subject.Contains("E=edib ........etc "))

                {

                    _certificate = cert;

                    break;

                }

            }

            store.Close();

            return _certificate;

        }

     

        // Sign an XML file and save the signature in a new file.

        public static void SignXmlFile(string FileName, string filePDF,string SignedFileName, string[] ElementsToSign)

        {

            // Check the arguments.  

            if (FileName == null)

                throw new ArgumentNullException("FileName");

            if (SignedFileName == null)

                throw new ArgumentNullException("SignedFileName");

            if (ElementsToSign == null)

                throw new ArgumentNullException("ElementsToSign");

     

            // Create a new XML document.

            XmlDocument doc = new XmlDocument();

            // Declare a signedXml object

            SignedXml signedXml = null;           

            try

            {

                doc.Load(FileName);

                // Format the document to ignore white spaces.

                doc.PreserveWhitespace = false;

                // Load the passed XML file using it's name.

                XmlNamespaceManager nsmanager;

                XmlNodeList messages;

                using (XmlTextReader reader = new XmlTextReader(FileName))

                {

                    nsmanager = new XmlNamespaceManager(reader.NameTable);

                    nsmanager.AddNamespace("eanucc", "urn:ean.ucc:2");

                    XmlElement element = doc.DocumentElement;

                    //Récuperer l'élément message

                    messages = element.SelectNodes("eanucc:message", nsmanager);

                    foreach (XmlNode message in messages)

                        element.RemoveChild(message);//Enlever l'élément message 

                }

                // Format the document to ignore white spaces.

                doc.PreserveWhitespace = false;

                //Initialize Certifcate

                GetCertificate();

                // Create a SignedXml object.

                signedXml = new XadesXml(doc);

                signedXml.Signature.Id = "Id1";

                // Add the key to the SignedXml document. 

                signedXml.SigningKey = _certificate.PrivateKey;

                // DataObject SignedPropertiesId

                signedXml.AddObject(CreateDataObject());

                // Création de l'élément XML contenant les données à signer

                XmlElement root = doc.CreateElement("Content", SignedXml.XmlDsigNamespaceUrl);

                root.InnerText = Convert.ToBase64String(File.ReadAllBytes(filePDF));

                // DataObject GS1_PDF

                XmlElement obj = doc.CreateElement("ds", "Object", "http://www.w3.org/2000/09/xmldsig#");

                DataObject dataObject = new DataObject("GS1_PDF", null, null, obj);

                dataObject.Data = root.ChildNodes;

                signedXml.AddObject(dataObject);

                // DataObject GS1_XML

                DataObject dataObjectGS1 = new DataObject("GS1_XML", null, null, obj);

                dataObjectGS1.Data = messages;

                signedXml.AddObject(dataObjectGS1);

     

                // Loop through each passed element to sign 

                // and create a reference.

                foreach (string s in ElementsToSign)

                {

                    // Create a reference to be signed.

                    Reference reference = new Reference();

                    reference.Uri = s;

                    if (s == "#SignedPropertiesId") reference.Type = "http://uri.etsi.org/01903/v1.3.2#SignedProperties";

                    // Add an enveloped transformation to the reference.

                    // Add the reference to the SignedXml object.

                    signedXml.AddReference(reference);

                }

     

                // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).

                KeyInfo keyInfo = new KeyInfo();

                keyInfo.AddClause(new KeyInfoX509Data(_certificate));

                signedXml.KeyInfo = keyInfo;

                // Compute the signature.

                signedXml.ComputeSignature();

            }

            catch (CryptographicException e)

            {

                Console.WriteLine(e.Message);

            }

            catch (Exception e)

            {

                Console.WriteLine(e.Message);

            }

            // 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.

            doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

            // Save the signed XML document to a file specified

            // using the passed string.

            XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));

            doc.WriteTo(xmltw);

            xmltw.Close();

        }

     

        // Verify the signature of an XML file and return the result.

        public static Boolean VerifyXmlSignature(String Name)

        {

            // Check the arguments.

            if (Name == null)

                throw new ArgumentNullException("Name");

            // Create a new XML document.

            XmlDocument doc = new XmlDocument();

            // Format using white spaces.

            doc.PreserveWhitespace = false;

            // Load the passed XML file into the document. 

            doc.Load(Name);

            // Create a new SignedXml object and pass it

            // the XML document class.

            SignedXml signedXml = new XadesXml(doc);

            // Find the "Signature" node and create a new

            // XmlNodeList object.

            XmlNodeList nodeList = doc.GetElementsByTagName("Signature");

            // Load the signature node.

            signedXml.LoadXml((XmlElement)nodeList[0]);

            // Check the signature and return the result.

            return signedXml.CheckSignature();

        }

     

     

        public static DataObject CreateDataObject( )

        {

            string xmlDsigUrl = SignedXml.XmlDsigNamespaceUrl;

            // Création de l'élément XML

            XmlDocument xmlDoc = new XmlDocument();

            // Création de l'élément racine

            XmlElement root = xmlDoc.CreateElement("root", xmlDsigUrl);

            // Ajout de l'élément QualifyingProperties

            root.AppendChild(QualifyingProperties(xmlDoc, xmlDsigUrl));

            // Ajout des données à signer

            DataObject dataObject = new DataObject();

            dataObject.Data = root.ChildNodes;

            return dataObject;

        }

     

        public static XmlNode QualifyingProperties(

                            XmlDocument xmlDoc,

                            string xmlDsigUrl)

        {

            string xadesUrl = "http://uri.etsi.org/01903/v1.3.2#";

            string dsUrl = "http://www.w3.org/2000/09/xmldsig#";

     

            // Création du bloc d'informations pour XAdES

            XmlElement QualifyingProperties = xmlDoc.CreateElement("xades", "QualifyingProperties", xadesUrl);

            // Création d'un lien vers le bloc de signature associé

            QualifyingProperties.Attributes.Append(xmlDoc.CreateAttribute("Id"));

            QualifyingProperties.Attributes["Id"].Value = "QualifyingdPropertiesId";

            QualifyingProperties.Attributes.Append(xmlDoc.CreateAttribute("Target"));

            QualifyingProperties.Attributes["Target"].Value = "#Id1";

     

            //SignedSignatureProperties

            XmlElement SignedSignatureProperties = xmlDoc.CreateElement("xades", "SignedSignatureProperties", xadesUrl);

     

            // Création de l'élément SignedProperties contenant les données XAdES à signer

            XmlElement signedProperties = xmlDoc.CreateElement("xades", "SignedProperties", xadesUrl);

            signedProperties.Attributes.Append(xmlDoc.CreateAttribute("Id"));

            signedProperties.Attributes["Id"].Value = "SignedPropertiesId";

     

            // Création de l'élément SigningTime

            XmlElement signingTime = xmlDoc.CreateElement("SigningTime");

            signingTime.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ");

     

            // Création de l'élément SigningCertificate

            XmlElement SigningCertificate = xmlDoc.CreateElement("xades", "SigningCertificate", xadesUrl);

            XmlElement Cert = xmlDoc.CreateElement("xades", "Cert", xadesUrl);

     

            //CertDigest

            XmlElement CertDigest = xmlDoc.CreateElement("xades", "CertDigest", xadesUrl);

            //DigestMethod

            XmlElement DigestMethod = xmlDoc.CreateElement("ds", "DigestMethod", dsUrl);

            XmlAttribute algo = xmlDoc.CreateAttribute("Algorithm");

            algo.Value = "http://www.w3.org/2000/09/xmldsig#sha1";

            DigestMethod.Attributes.Append(algo);

            CertDigest.AppendChild(DigestMethod);

            //DigestValue

            XmlElement DigestValue = xmlDoc.CreateElement("ds", "DigestValue", dsUrl);

            DigestValue.InnerText = _certificate.GetCertHashString();

            CertDigest.AppendChild(DigestValue);

            //IssuerSerial

            XmlElement IssuerSerial = xmlDoc.CreateElement("xades", "IssuerSerial", xadesUrl);

            //X509IssuerName

            XmlElement X509IssuerName = xmlDoc.CreateElement("ds", "X509IssuerName", dsUrl);

            X509IssuerName.InnerText = _certificate.SubjectName.Name;

            IssuerSerial.AppendChild(X509IssuerName);

            //X509SerialNumber

            XmlElement X509SerialNumber = xmlDoc.CreateElement("ds", "X509SerialNumber", dsUrl);

            X509SerialNumber.InnerText = _certificate.GetSerialNumberString();

            IssuerSerial.AppendChild(X509SerialNumber);

     

            Cert.AppendChild(CertDigest);

            Cert.AppendChild(IssuerSerial);

            SigningCertificate.AppendChild(Cert);

            signedProperties.AppendChild(signingTime);

            signedProperties.AppendChild(SigningCertificate);

            QualifyingProperties.AppendChild(signedProperties);

            return QualifyingProperties;

        }

    }//Classe SignEnveloping

     

     

     

    Merci.

     

    jeudi 17 juin 2010 12:25