Skip to main content
Post a question

Notifications

Community site session details

Community site session details

Session Id : iEy+qHl+c10BXckeMMVBrU
Finance | Project Operations, Human Resources, ...
Answered

Problem signing XML that would later be use in a D365FO project

Like (1) ShareShare
ReportReport
Posted on 15 May 2023 18:02:48 by 148

Hi,

I'm building code in C# that later I will integrate it in a D365FO project. This code needs to sign an XMLDocument with a valid certificate I have and then later I have to send it to a web service. The problem is that when I get to this line: signedXml.ComputeSignature(); There is an error message that says that the algorithm use is not valid. The algorithm that I use is RSA-SHA256 and I already checked with windows certificates and indeed that algorithm is part of the certificate properties.

Here is the full code (I hid some of the urls and file info):

using System;
using System.Text;
using System.Xml;
using Console = System.Console;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;


namespace FirmaElectronica
{
    class Program
    {
        static void Main(string[] args)
        {
            // Definimos los parámetros de la petición
            string urlServicio = "https://url.com";
            string archivoXML = "C:\\Users\\...\\file.xml";
            string claveAcceso = "0000000000000000000000000000000000000000000000000";
            string rutaArchivoConfiguracion = "C:\\Users\\....\\file.txt";
            string clave = "";

            // Método para guardar clave en la variable
            if (File.Exists(rutaArchivoConfiguracion))
            {
                string[] lineas = File.ReadAllLines(rutaArchivoConfiguracion);

                foreach (string linea in lineas)
                {
                    if (linea.StartsWith("clave="))
                    {
                        clave = linea.Substring(6);
                        break;
                    }
                }
            }

            if (string.IsNullOrEmpty(clave))
            {
                throw new Exception("No se encontrĂł la clave en el archivo de configuraciĂłn.");
            }

            // Leemos el archivo XML
            string xml = System.IO.File.ReadAllText(archivoXML, Encoding.UTF8);

            // Convertimos la cadena a un objeto XmlDocument
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);

            // Leemos el certificado desde el archivo .p12 y proporcionamos la clave
            X509Certificate2 certificate = new X509Certificate2("C:\\Users\\....\\file.p12", clave, X509KeyStorageFlags.Exportable);

            // Creamos el objeto SignedXml y lo configuramos
            SignedXml signedXml = new SignedXml(xmlDoc);
            signedXml.SigningKey = certificate.PrivateKey;
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

            // Creamos una referencia al objeto SignedXml
            Reference reference = new Reference();
            reference.Uri = "";

            // Agregamos el transform para la referencia
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
            reference.AddTransform(env);

            // Agregamos la referencia al objeto SignedXml
            signedXml.AddReference(reference);

            // Creamos el objeto KeyInfo y lo configuramos
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.AddClause(new KeyInfoX509Data(certificate));

            // Agregamos el objeto KeyInfo al objeto SignedXml
            signedXml.KeyInfo = keyInfo;

            // Especificamos el algoritmo de firma
            signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA256Url;

            // Firmamos el XML
            signedXml.ComputeSignature(); //HERE IT STOPS

            // Obtenemos la representaciĂłn del XML firmado como objeto XmlElement
            XmlElement xmlDigitalSignature = signedXml.GetXml();

            // Agregamos el elemento firmado al XML original
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));

            // Convertimos el XML firmado a cadena
            string xmlFirmado = xmlDoc.OuterXml;

            // Armamos el cuerpo del mensaje SOAP
            string cuerpoMensaje = ""  
                                    ""  
                                    ""  
                                        ""  
                                            ""   claveAcceso   ""  
                                            ""   xmlFirmado   ""  
                                        ""  
                                    ""  
                                "";


            // Creamos la peticiĂłn HTTP
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlServicio);
            request.Method = "POST";
            request.ContentType = "text/xml;charset=UTF-8";
            request.Headers.Add("SOAPAction", "");

            // Establecemos el tamaño del contenido que se va a enviar en la petición
            request.ContentLength = cuerpoMensaje.Length;

            // Escribimos el cuerpo del mensaje SOAP en el stream de la peticiĂłn
            using (Stream stream = request.GetRequestStream())
            {
                using (StreamWriter sw = new StreamWriter(stream))
                {
                    sw.Write(cuerpoMensaje);
                }
            }

            // Obtenemos la respuesta del servicio web
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                // Leemos la respuesta
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    string responseXml = reader.ReadToEnd();

                    // Parseamos la respuesta como XML
                    XmlDocument xmlDocResponse = new XmlDocument();
                    xmlDocResponse.LoadXml(responseXml);

                    // Extraemos el estado de la autorizaciĂłn
                    string estado = xmlDocResponse.GetElementsByTagName("estado")[0].InnerText;

                    if (estado == "AUTORIZADO")
                    {
                        // El comprobante fue autorizado
                        Console.WriteLine("El comprobante fue autorizado");
                    }
                    else
                    {
                        // El comprobante fue rechazado o está en proceso
                        Console.WriteLine("El comprobante fue rechazado o está en proceso");
                    }
                }
            }
        }
    }
}



Thanks in advance.

  • Anton Venter Profile Picture
    19,595 Super User 2025 Season 1 on 16 May 2023 at 05:46:33
    RE: Problem signing XML that would later be use in a D365FO project

    You are welcome :-)

  • Daniel Mora Profile Picture
    148 on 15 May 2023 at 19:33:09
    RE: Problem signing XML that would later be use in a D365FO project

    Thanks Anton, I just had to change signedXml.SigningKey = certificate.PrivateKey; for signedXml.SigningKey = certificate.GetRSAPrivateKey(); because it seems is this way for .Net 4.7.1 and above.

  • Verified answer
    Anton Venter Profile Picture
    19,595 Super User 2025 Season 1 on 15 May 2023 at 19:22:54
    RE: Problem signing XML that would later be use in a D365FO project

    Have a look at this article, it says SHA-256 isn't supported by X509Certificate2 and the article describes the same error as you "invalid algorithm used"

    https://stackoverflow.com/questions/29005876/signedxml-compute-signature-with-sha256

  • Daniel Mora Profile Picture
    148 on 15 May 2023 at 19:17:40
    RE: Problem signing XML that would later be use in a D365FO project

    Main message:

    System.Security.Cryptography.CryptographicException: 'Specified algorithm is invalid.

    Full details:

    System.Security.Cryptography.CryptographicException

     HResult=0x80090008

     Message = Specified algorithm is invalid.

     Origin = mscorlib

    Stack trace:

      at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)

      at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)

      at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)

      at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)

      at System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash)

      at System.Security.Cryptography.AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm hash)

      at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()

      at FirmaElectronica.Program.Main(String[] args) in C:\Users\......\Program.cs:line 85

  • Martin Dráb Profile Picture
    232,942 Most Valuable Professional on 15 May 2023 at 19:12:04
    RE: Problem signing XML that would later be use in a D365FO project

    What is the type of the exception and the exact error message?

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

🌸 Community Spring Festival 2025 Challenge 🌸

WIN Power Platform Community Conference 2025 tickets!

Jonas ”Jones” Melgaard – Community Spotlight

We are honored to recognize Jonas "Jones" Melgaard as our April 2025…

Kudos to the March Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 294,161 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 232,942 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,158 Moderator

Leaderboard

Product updates

Dynamics 365 release plans
Loading started