using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Runtime.InteropServices; using System.Xml; // Namespace para organizar nosso código namespace ComponenteAssinatura { // GUIDs são números de identificação únicos para o COM [Guid("A1B2C3D4-1234-5678-ABCD-1234567890AB")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] [ComVisible(true)] public interface IAssinadorESocial { [DispId(1)] string Assinar(string xmlString, string idElementoAssinar, string numeroSerieCertificado); } [Guid("B2C3D4E5-2345-6789-BCDE-2345678901BC")] [ClassInterface(ClassInterfaceType.None)] [ProgId("Componente.AssinadorESocial")] // Nome que você usará para criar o objeto [ComVisible(true)] public class AssinadorESocial : IAssinadorESocial { public string Assinar(string xmlString, string idElementoAssinar, string numeroSerieCertificado) { try { // 1. Encontrar o Certificado Digital pelo número de série X509Certificate2 certificado = null; var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); foreach (X509Certificate2 cert in store.Certificates) { if (cert.SerialNumber.Equals(numeroSerieCertificado, StringComparison.InvariantCultureIgnoreCase)) { certificado = cert; break; } } store.Close(); if (certificado == null) { return "ERRO: Certificado com número de série '" + numeroSerieCertificado + "' não encontrado."; } if (!certificado.HasPrivateKey) { return "ERRO: O certificado encontrado não possui uma chave privada."; } // 2. Carregar o XML que veio como texto var doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(xmlString); // 3. Preparar o objeto de assinatura usando a chave privada do certificado var signedXml = new SignedXml(doc); signedXml.SigningKey = certificado.GetRSAPrivateKey(); // 4. Criar a referência ao elemento que queremos assinar (ex: #ID123...) var reference = new Reference(); reference.Uri = "#" + idElementoAssinar; // Adicionar as transformações padrão para eSocial reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform()); signedXml.AddReference(reference); // 5. Adicionar as informações do certificado na assinatura var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificado)); signedXml.KeyInfo = keyInfo; // 6. Calcular a assinatura signedXml.ComputeSignature(); // 7. Obter o XML da assinatura (...) XmlElement xmlDigitalSignature = signedXml.GetXml(); // 8. Anexar a assinatura ao elemento correto no documento XML doc.GetElementsByTagName("evento")[0].AppendChild(xmlDigitalSignature); // 9. Retornar o XML completo e assinado como texto return doc.OuterXml; } catch (Exception ex) { // Se qualquer erro ocorrer, retorna uma mensagem clara return "ERRO: " + ex.Message; } } } }