[Python] Assinatura e inserção de XML com Python

Discussão em 'Python' iniciado por Stack, Dezembro 19, 2024.

  1. Stack

    Stack Membro Participativo

    Estou tentando enviar um XML de evento assinado para a Receita Federal, mas quando insiro esse evento em um XML de lote, a assinatura é invalidada. Estou utilizando Python para assinar o XML do evento com a biblioteca signxml (método enveloped), mas após a inserção, o XML de evento assinado dentro do lote gera erro de "cifra assimétrica inválida" na validação.

    Alguém sabe qual é a melhor forma de garantir que a assinatura do evento se mantenha válida após a inserção no XML de lote?

    Assino o XML do evento usando o signxml com o método enveloped e insiro o XML de evento assinado dentro de um XML de lote que contém outros eventos:

    from lxml import etree
    from signxml import XMLSigner, methods
    from cryptography.hazmat.primitives.serialization import pkcs12

    # Extrair chave privada e certificado
    private_key, cert, _ = pkcs12.load_key_and_certificates(pfx_data, cert_password)

    # Carregar o XML
    xml_str = '''
    <Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/evt4020PagtoBeneficiarioPJ/v2_01_02">
    <EvtPJ id="ID123">
    <cnpj>123456789</cnpj>
    </EvtPJ>
    </Reinf>
    '''
    root = etree.fromstring(xml_str)

    # Configurar o XMLSigner
    signer = XMLSigner(method=methods.enveloped, signature_algorithm="rsa-sha256", digest_algorithm="sha256")

    # Assinar o XML (referenciando o ID da tag EvtPJ)
    signed_root = signer.sign(root, key=private_key, cert=[cert], reference_uri="#ID123")

    # Carregar o XML do lote
    main_xml_str = '''
    <Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/envioLoteEventosAssincrono/v1_00_00">
    <lote>
    <eventos>
    <evento id="ID123">
    </evento>
    </eventos>
    </lote>
    </Reinf>
    '''
    main_root = etree.fromstring(main_xml_str)

    # Encontrar a tag <evento> correspondente ao ID
    evento_element = main_root.find(".//{http://www.reinf.esocial.gov.br/schemas/envioLoteEventosAssincrono/v1_00_00}evento[@id='ID123']")

    if evento_element is not None:
    # Inserir o XML assinado dentro da tag <evento>
    evento_element.append(signed_root)
    else:
    print("Elemento <evento> com o ID especificado não encontrado.")

    # Converter o XML principal para string formatada
    final_xml = etree.tostring(main_root, pretty_print=False, xml_declaration=False, encoding="utf-8")

    # Salvar o XML final em um arquivo
    with open("xml_final.xml", "wb") as file:
    file.write(final_xml)


    O XML de lote com o XML de evento inserido:

    <Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/envioLoteEventosAssincrono/v1_00_00">
    <lote>
    <eventos>
    <evento id="ID123">
    <Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/evt4020PagtoBeneficiarioPJ/v2_01_02">
    <EvtPJ id="ID123">
    <cnpj>123456789</cnpj>
    </EvtPJ>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#ID123"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>[...]</ds:DigestValue></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>
    </lote>
    </Reinf>

    Continue reading...

Compartilhe esta Página