Bom dia,
Estou usando esse método em C# para fazer a assinatura dos xml, consegui fazer as requisições via SOAP UI, veja se te ajuda.
public static void AssinarXML(XmlDocument xmlDoc, X509Certificate2 certificado, string tag, string id = "")
{
// Verifica se a tag existe no XML
XmlElement elemento = xmlDoc.GetElementsByTagName(tag)[0] as XmlElement;
if (elemento == null)
{
throw new Exception($"Tag {tag} não encontrada no XML.");
}
// Inicializa o SignedXml
SignedXml signedXml = new SignedXml(xmlDoc);
// Obtém a chave privada do certificado
RSACryptoServiceProvider rsaProvider = certificado.PrivateKey as RSACryptoServiceProvider;
if (rsaProvider == null)
{
throw new Exception("Certificado não contém chave privada.");
}
// Definindo a chave de assinatura
signedXml.SigningKey = certificado.PrivateKey;
// Criando o SignedInfo
SignedInfo signedInfo = new SignedInfo
{
CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl, // Canonicalização do XML
SignatureMethod = SignedXml.XmlDsigRSASHA1Url // Método de assinatura SHA1
};
// Se o id não for informado, iremos assinar o próprio elemento diretamente
string uri = string.IsNullOrEmpty(id) ? "" : $"#{id}";
// Criando a referência para o elemento a ser assinado
Reference reference = new Reference
{
Uri = uri // Se id vazio, será aplicada à tag inteira
};
// Adicionando a transformação (enveloped e canonicalização)
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); // Transformação para assinatura envelopada
reference.AddTransform(new XmlDsigC14NTransform()); // Canonicalização
// Adiciona a referência ao SignedInfo
signedInfo.AddReference(reference);
// Agora, adicionamos a SignedInfo ao SignedXml corretamente
signedXml.AddReference(reference);
// Adicionando a informação da chave (somente o certificado x509, sem outras tags)
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificado, X509IncludeOption.EndCertOnly));
signedXml.KeyInfo = keyInfo;
// Calculando a assinatura
signedXml.ComputeSignature();
// Obtendo a assinatura XML gerada
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Verifica se deve adicionar ao nó pai ou ao próprio elemento
if (tag == "ConsultarLoteRpsEnvio")
{
elemento.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
else
{
elemento.ParentNode.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
}
As chamadas ficam assim
// EnviarLoteRpsSincronoEnvio
XmlSigner.AssinarXML(xmlLote, certificado, "InfDeclaracaoPrestacaoServico", "inf7");
// ConsultarLoteRpsEnvio
XmlSigner.AssinarXML(xmlLote, certificado, "ConsultarLoteRpsEnvio");
// CancelarNfseEnvio
XmlSigner.AssinarXML(xmlLote, certificado, "InfPedidoCancelamento");