Eu estou desenvolvendo um script de envio de eventos em lote em XML de forma assíncrona para o webservice Reinf usando Python 3.9, porém estou com problemas de assinatura, que sempre retorna a mensagem de erro MS0017: <codResp>MS0017</codResp> <dscResp>Assinatura do evento inválida. Erro ao verificar a assinatura (tag 'Signature') com o certificado (tag 'X509Certificate'). Verifique se houve alteracao no arquivo apos o mesmo ter sido assinado. </dscResp> Eu li em outras respostas de problemas parecidos que o jeito correto é assinar cada evento individualmente e depois disso embutir eles no xml de lote, porém acho que isso está invalidando as assinaturas. Estou testando com somente um evento R-4020, mas até agora não consegui resolver o problema da assinatura. Segue o meu código abaixo e um exemplo de xml que eu utilizei. Python: from lxml import etree from signxml import XMLSigner, methods from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend from fazer_requisicao import fazer_requisicao def carregar_certificados(cert_path, key_path): """Carrega o certificado e a chave privada.""" with open(cert_path, "rb") as cert_file: cert_data = cert_file.read() with open(key_path, "rb") as key_file: key_data = key_file.read() private_key = serialization.load_pem_private_key( key_data, password=None, backend=default_backend() ) return cert_data, private_key def ler_xml(file_path): """Lê e retorna o conteúdo do XML como um elemento do lxml.""" with open(file_path, "r", encoding='utf-8') as xml_file: xml_content = xml_file.read() return etree.fromstring(xml_content.encode('utf-8')) def limpar_atributos_desnecessarios(root): """Remove atributos desnecessários do XML.""" for elem in root.getiterator(): if 'xsi' in elem.attrib: del elem.attrib['xsi'] if 'xsd' in elem.attrib: del elem.attrib['xsd'] def obter_event_id(root): """Obtém o ID do evento no XML.""" for elem in root.iter(): if 'id' in elem.attrib: return elem.attrib['id'] raise ValueError("No ID attribute found in the XML.") def assinar_xml(root, private_key, cert_data, event_id): """Assina o XML usando o certificado e a chave privada.""" signer = XMLSigner( method=methods.enveloped, digest_algorithm='sha256', c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315' ) return signer.sign( root, key=private_key, cert=cert_data, reference_uri=event_id ) def criar_documento_externo(event_id, signed_root): """Cria o documento XML externo incluindo o evento assinado.""" external_root = etree.Element( "Reinf", attrib={"xmlns": "http://www.reinf.esocial.gov.br/schemas/envioLoteEventosAssincrono/v1_00_00"} ) envio_lote_eventos = etree.SubElement(external_root, "envioLoteEventos") ide_contribuinte = etree.SubElement(envio_lote_eventos, "ideContribuinte") etree.SubElement(ide_contribuinte, "tpInsc").text = "1" etree.SubElement(ide_contribuinte, "nrInsc").text = "12345678000195" eventos = etree.SubElement(envio_lote_eventos, "eventos") evento = etree.SubElement(eventos, "evento", Id=event_id) evento.append(signed_root) return external_root def salvar_xml(file_path, xml_content): """Salva o XML no arquivo especificado.""" with open(file_path, "w", encoding="utf-8") as f: f.write(etree.tostring(xml_content, pretty_print=False, encoding="utf-8").decode("utf-8")) def processar_xml(cert_path, key_path, xml_path, output_signed, output_final): """Processa o XML: carrega, assina e cria o documento final.""" cert_data, private_key = carregar_certificados(cert_path, key_path) root = ler_xml(xml_path) limpar_atributos_desnecessarios(root) event_id = obter_event_id(root) signed_root = assinar_xml(root, private_key, cert_data, event_id) salvar_xml(output_signed, signed_root) final_document = criar_documento_externo(event_id, signed_root) salvar_xml(output_final, final_document) fazer_requisicao(etree.tostring(final_document, pretty_print=False, encoding="utf-8").decode("utf-8")) # Exemplo de execução processar_xml( cert_path="certificado.pem", key_path="chave_privada.pem", xml_path="evento.xml", output_signed="signed_document.xml", output_final="final_document.xml" ) XML final enviado: <Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/envioLoteEventosAssincrono/v1_00_00"><envioLoteEventos><ideContribuinte><tpInsc>1</tpInsc><nrInsc>12345678000195</nrInsc></ideContribuinte><eventos><evento Id="ID1123451234512342024121013140000000"><Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/evt4020PagtoBeneficiarioPJ/v2_01_02"> <evtRetPJ id="ID1123451234512342024121013140000000"> <ideEvento> <indRetif>1</indRetif> <nrRecibo>123456789-01-2023-0001-123456789</nrRecibo> <perApur>2023-08</perApur> <tpAmb>2</tpAmb> <procEmi>1</procEmi> <verProc>1.0</verProc> </ideEvento> <ideContri> <tpInsc>1</tpInsc> <nrInsc>12345123451234</nrInsc> <infoComplContri> <natJur>1234</natJur> </infoComplContri> </ideContri> <ideEstab> <tpInscEstab>1</tpInscEstab> <nrInscEstab>12341234123412</nrInscEstab> <ideBenef> <cnpjBenef>12341234123412</cnpjBenef> <nmBenef>Empresa Beneficiária</nmBenef> <isenImun>2</isenImun> <idePgto> <natRend>12345</natRend> <infoPgto> <dtFG>2023-08-25</dtFG> <vlrBruto>1000,00</vlrBruto> </infoPgto> </idePgto> </ideBenef> </ideEstab> </evtRetPJ> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#ID1010726900001572024121013140000000"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></ds:Transforms><dsigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><dsigestValue>[...]</dsigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>[...]</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>[...] </ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></Reinf></evento></eventos></envioLoteEventos></Reinf> Continue reading...