def assinarNfse(self, xml, retorna_string=True): "Assina NFS-e" try: # define variaveis de acordo com autorizador if self.autorizador == 'ginfes': xpath = './/ns2:InfRps' tag = 'InfRps' elif self.autorizador == 'betha': xpath = './/ns1:InfDeclaracaoPrestacaoServico' tag = 'InfDeclaracaoPrestacaoServico' else: raise Exception('Autorizador não encontrado!') xml = etree.fromstring(xml) # define namespaces, pega do proprio xml namespaces = xml.nsmap # No raiz do XML de saida raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Tenta achar a tag ref = etree.SubElement(siginfo, 'Reference', URI='#' + xml.xpath(xpath, namespaces=namespaces)[0].attrib['Id']) trans = etree.SubElement(ref, 'Transforms') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') rps = xml.xpath(xpath+'/..', namespaces=namespaces)[0] rps.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: texto = remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False)) # se for tag do Betha if tag == 'InfDeclaracaoPrestacaoServico': texto = texto.replace('ns1:', '').replace(':ns1', '') arquivo.write(texto) subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'nfse.xml', '--id-attr:Id', tag, 'nfse.xml']) if retorna_string: return open('nfse.xml', 'r').read() else: return etree.parse('nfse.xml').getroot() except Exception as e: raise e
def assinarCancelar(self, xml, retorna_string=True): """ Método que assina o xml para cancelamento de NFS-e """ try: if self.autorizador == 'ginfes': xpath = 'CancelarNfseEnvio' tag = 'CancelarNfseEnvio' namespaces = {'ns1': 'http://www.ginfes.com.br/servico_cancelar_nfse_envio', 'ns2':'http://www.ginfes.com.br/tipos'} elif self.autorizador == 'betha': xpath = '/CancelarNfseEnvio/ns1:Pedido' tag = 'InfPedidoCancelamento' namespaces = {'ns1': 'http://www.betha.com.br/e-nota-contribuinte-ws'} else: raise Exception('Autorizador não encontrado!') xml = etree.fromstring(xml) # No raiz do XML de saida raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Tenta achar a tag informada no xpath if tag == 'InfPedidoCancelamento': ref = etree.SubElement(siginfo, 'Reference', URI='#'+xml.xpath('.//ns1:'+tag, namespaces=namespaces)[0].attrib['Id']) # ginfes não tem id no cancelamento v2 else: ref = etree.SubElement(siginfo, 'Reference', URI='') trans = etree.SubElement(ref, 'Transforms') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') if tag == 'InfPedidoCancelamento': xml = xml.xpath(xpath, namespaces=namespaces)[0] # ginfes só possui a tag root else: xml.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: arquivo.write(remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n',''))) subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml']) if retorna_string: return open('funfa.xml', 'r').read() else: return etree.parse('funfa.xml').getroot() except Exception as e: raise e
def post(self): # Obtem o body da request xml = self.request.body # Transforma em etree raiz = etree.parse(StringIO(xml)) # Extrai a tag do método da request tag = extrair_tag(raiz.getroot().getchildren()[0].getchildren()[0]) # Chama o método respectivo para a tag print 'Metodo:', tag getattr(self, tag)(raiz)
def assinar_arquivo(self, caminho_arquivo, salva=True): # Carrega o XML do arquivo raiz = etree.parse(caminho_arquivo) # Efetua a assinatura xml = self.assinar_etree(raiz, retorna_xml=True) # Grava XML assinado no arquivo if salva: fp = file(caminho_arquivo, 'w') fp.write(xml) fp.close() return xml
def _assinar(self, xml, tag, retorna_string=True): """ Método para assinar xml de NFS-e com tags sem ID Consulta de Lote e Consulta por RPS @param tag - raiz do xml que será assinado """ try: xml = etree.fromstring(xml) # No raiz do XML de saida raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Consulta nao tem id ref = etree.SubElement(siginfo, 'Reference', URI='') trans = etree.SubElement(ref, 'Transforms') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') xml.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: arquivo.write(remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n',''))) subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml']) xml = etree.parse('funfa.xml').getroot() if retorna_string: return etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n','') else: return xml except Exception as e: raise e
def assinar(self, xml, retorna_string=False): try: # No raiz do XML de saida tag = 'infNFe' # tag que será assinada raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Tenta achar a tag infNFe try: ref = etree.SubElement(siginfo, 'Reference', URI='#'+xml.findall('infNFe')[0].attrib['Id']) # Caso nao tenha a tag infNFe, procura a tag infEvento except IndexError: tag = 'infEvento' ref = etree.SubElement(siginfo, 'Reference', URI='#'+xml.findall('infEvento')[0].attrib['Id']) trans = etree.SubElement(ref, 'Transforms') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') xml.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('testes.xml', 'w') as arquivo: arquivo.write(remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False))) subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'testes.xml']) xml = etree.parse('funfa.xml').getroot() if retorna_string: return etree.tostring(xml, encoding="unicode", pretty_print=False) else: return xml except Exception as e: raise e
def assinarConsulta(self, xml, retorna_string=True): try: xml = etree.fromstring(xml) # No raiz do XML de saida tag = 'ns1:ConsultarNfseEnvio' # tag que será assinada raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Consulta nao tem id ref = etree.SubElement(siginfo, 'Reference', URI='') trans = etree.SubElement(ref, 'Transforms') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement(ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') consulta = xml.xpath('/ns1:ConsultarNfseEnvio', namespaces={'ns1': 'http://www.ginfes.com.br/servico_consultar_nfse_envio_v03.xsd', 'ns2':'http://www.ginfes.com.br/tipos_v03.xsd'})[0] consulta.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: arquivo.write(remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n',''))) subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml']) xml = etree.parse('funfa.xml').getroot() if retorna_string: return etree.tostring(xml, encoding="unicode", pretty_print=False) else: return xml except Exception as e: raise e
def assinar_etree(self, raiz, retorna_xml=False): # Extrai a tag do elemento raiz tipo = extrair_tag(raiz.getroot()) # doctype compatível com o tipo da tag raiz if tipo == u'NFe': doctype = u'<!DOCTYPE NFe [<!ATTLIST infNFe Id ID #IMPLIED>]>' elif tipo == u'inutNFe': doctype = u'<!DOCTYPE inutNFe [<!ATTLIST infInut Id ID #IMPLIED>]>' elif tipo == u'cancNFe': doctype = u'<!DOCTYPE cancNFe [<!ATTLIST infCanc Id ID #IMPLIED>]>' elif tipo == u'DPEC': doctype = u'<!DOCTYPE DPEC [<!ATTLIST infDPEC Id ID #IMPLIED>]>' # Tag de assinatura if raiz.getroot().find('Signature') is None: signature = etree.Element( '{%s}Signature' % NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id'], nsmap={'sig': NAMESPACE_SIG}, ) signed_info = etree.SubElement(signature, '{%s}SignedInfo' % NAMESPACE_SIG) etree.SubElement( signed_info, 'CanonicalizationMethod', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement( signed_info, 'SignatureMethod', Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1") reference = etree.SubElement( signed_info, '{%s}Reference' % NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id']) transforms = etree.SubElement( reference, 'Transforms', URI=raiz.getroot().getchildren()[0].attrib['Id']) etree.SubElement( transforms, 'Transform', Algorithm= "http://www.w3.org/2000/09/xmldsig#enveloped-signature") etree.SubElement( transforms, 'Transform', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement( reference, '{%s}DigestMethod' % NAMESPACE_SIG, Algorithm="http://www.w3.org/2000/09/xmldsig#sha1") digest_value = etree.SubElement(reference, '{%s}DigestValue' % NAMESPACE_SIG) signature_value = etree.SubElement( signature, '{%s}SignatureValue' % NAMESPACE_SIG) key_info = etree.SubElement(signature, '{%s}KeyInfo' % NAMESPACE_SIG) x509_data = etree.SubElement(key_info, '{%s}X509Data' % NAMESPACE_SIG) x509_certificate = etree.SubElement( x509_data, '{%s}X509Certificate' % NAMESPACE_SIG) raiz.getroot().insert(0, signature) # Acrescenta a tag de doctype (como o lxml nao suporta alteracao do doctype, # converte para string para faze-lo) xml = etree.tostring(raiz, xml_declaration=True, encoding='utf-8') if xml.find('<!DOCTYPE ') == -1: pos = xml.find('>') + 1 xml = xml[:pos] + doctype + xml[pos:] #raiz = etree.parse(StringIO(xml)) doc_xml, ctxt, noh_assinatura, assinador = self._antes_de_assinar_ou_verificar( raiz) # Realiza a assinatura assinador.sign(noh_assinatura) # Coloca na instância Signature os valores calculados digest_value.text = ctxt.xpathEval( u'//sig:DigestValue')[0].content.replace(u'\n', u'') signature_value.text = ctxt.xpathEval( u'//sig:SignatureValue')[0].content.replace(u'\n', u'') # Provavelmente retornarão vários certificados, já que o xmlsec inclui a cadeia inteira certificados = ctxt.xpathEval(u'//sig:X509Data/sig:X509Certificate') x509_certificate.text = certificados[len(certificados) - 1].content.replace(u'\n', u'') resultado = assinador.status == xmlsec.DSigStatusSucceeded # Gera o XML para retornar xml = doc_xml.serialize() # Limpa objetos da memoria e desativa funções criptográficas self._depois_de_assinar_ou_verificar(doc_xml, ctxt, assinador) if retorna_xml: return xml else: return etree.parse(StringIO(xml))
def assinar_xml(self, xml): raiz = etree.parse(StringIO(xml)) # Efetua a assinatura return self.assinar_etree(raiz, retorna_xml=True)
def verificar_xml(self, xml): raiz = etree.parse(StringIO(xml)) return self.verificar_etree(raiz)
def assinar_etree(self, raiz, retorna_xml=False): # Extrai a tag do elemento raiz tipo = extrair_tag(raiz.getroot()) # doctype compatível com o tipo da tag raiz if tipo == u'NFe': doctype = u'<!DOCTYPE NFe [<!ATTLIST infNFe Id ID #IMPLIED>]>' elif tipo == u'inutNFe': doctype = u'<!DOCTYPE inutNFe [<!ATTLIST infInut Id ID #IMPLIED>]>' elif tipo == u'cancNFe': doctype = u'<!DOCTYPE cancNFe [<!ATTLIST infCanc Id ID #IMPLIED>]>' elif tipo == u'DPEC': doctype = u'<!DOCTYPE DPEC [<!ATTLIST infDPEC Id ID #IMPLIED>]>' # Tag de assinatura if raiz.getroot().find('Signature') is None: signature = etree.Element( '{%s}Signature'%NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id'], nsmap={'sig': NAMESPACE_SIG}, ) signed_info = etree.SubElement(signature, '{%s}SignedInfo'%NAMESPACE_SIG) etree.SubElement(signed_info, 'CanonicalizationMethod', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement(signed_info, 'SignatureMethod', Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1") reference = etree.SubElement(signed_info, '{%s}Reference'%NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id']) transforms = etree.SubElement(reference, 'Transforms', URI=raiz.getroot().getchildren()[0].attrib['Id']) etree.SubElement(transforms, 'Transform', Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature") etree.SubElement(transforms, 'Transform', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement(reference, '{%s}DigestMethod'%NAMESPACE_SIG, Algorithm="http://www.w3.org/2000/09/xmldsig#sha1") digest_value = etree.SubElement(reference, '{%s}DigestValue'%NAMESPACE_SIG) signature_value = etree.SubElement(signature, '{%s}SignatureValue'%NAMESPACE_SIG) key_info = etree.SubElement(signature, '{%s}KeyInfo'%NAMESPACE_SIG) x509_data = etree.SubElement(key_info, '{%s}X509Data'%NAMESPACE_SIG) x509_certificate = etree.SubElement(x509_data, '{%s}X509Certificate'%NAMESPACE_SIG) raiz.getroot().insert(0, signature) # Acrescenta a tag de doctype (como o lxml nao suporta alteracao do doctype, # converte para string para faze-lo) xml = etree.tostring(raiz, xml_declaration=True, encoding='utf-8') if xml.find('<!DOCTYPE ') == -1: pos = xml.find('>') + 1 xml = xml[:pos] + doctype + xml[pos:] #raiz = etree.parse(StringIO(xml)) doc_xml, ctxt, noh_assinatura, assinador = self._antes_de_assinar_ou_verificar(raiz) # Realiza a assinatura assinador.sign(noh_assinatura) # Coloca na instância Signature os valores calculados digest_value.text = ctxt.xpathEval(u'//sig:DigestValue')[0].content.replace(u'\n', u'') signature_value.text = ctxt.xpathEval(u'//sig:SignatureValue')[0].content.replace(u'\n', u'') # Provavelmente retornarão vários certificados, já que o xmlsec inclui a cadeia inteira certificados = ctxt.xpathEval(u'//sig:X509Data/sig:X509Certificate') x509_certificate.text = certificados[len(certificados)-1].content.replace(u'\n', u'') resultado = assinador.status == xmlsec.DSigStatusSucceeded # Gera o XML para retornar xml = doc_xml.serialize() # Limpa objetos da memoria e desativa funções criptográficas self._depois_de_assinar_ou_verificar(doc_xml, ctxt, assinador) if retorna_xml: return xml else: return etree.parse(StringIO(xml))
def _assinar(self, xml, tag, retorna_string=True): """ Método para assinar xml de NFS-e com tags sem ID Consulta de Lote e Consulta por RPS @param tag - raiz do xml que será assinado """ try: xml = etree.fromstring(xml) # No raiz do XML de saida raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement( siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Consulta nao tem id ref = etree.SubElement(siginfo, 'Reference', URI='') trans = etree.SubElement(ref, 'Transforms') etree.SubElement( trans, 'Transform', Algorithm= 'http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement( trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') xml.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: arquivo.write( remover_acentos( etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n', ''))) subprocess.check_call([ 'xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml' ]) xml = etree.parse('funfa.xml').getroot() if retorna_string: return etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n', '') else: return xml except Exception as e: raise e
def assinarConsulta(self, xml, retorna_string=True): try: xml = etree.fromstring(xml) # No raiz do XML de saida tag = 'ns1:ConsultarNfseEnvio' # tag que será assinada raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement( siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Consulta nao tem id ref = etree.SubElement(siginfo, 'Reference', URI='') trans = etree.SubElement(ref, 'Transforms') etree.SubElement( trans, 'Transform', Algorithm= 'http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement( trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') consulta = xml.xpath( '/ns1:ConsultarNfseEnvio', namespaces={ 'ns1': 'http://www.ginfes.com.br/servico_consultar_nfse_envio_v03.xsd', 'ns2': 'http://www.ginfes.com.br/tipos_v03.xsd' })[0] consulta.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: arquivo.write( remover_acentos( etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n', ''))) subprocess.check_call([ 'xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml' ]) xml = etree.parse('funfa.xml').getroot() if retorna_string: return etree.tostring(xml, encoding="unicode", pretty_print=False) else: return xml except Exception as e: raise e
def assinar(self, xml, retorna_string=False): try: # No raiz do XML de saida tag = 'infNFe' # tag que será assinada raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement( siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Tenta achar a tag infNFe try: if len(xml.nsmap.items()) == 0: # não tem namespace ref = etree.SubElement( siginfo, 'Reference', URI='#' + xml.findall('infNFe')[0].attrib['Id']) else: ns = {'ns': 'http://www.portalfiscal.inf.br/nfe'} ref = etree.SubElement( siginfo, 'Reference', URI='#' + xml.findall('ns:infNFe', namespaces=ns)[0].attrib['Id']) # Caso nao tenha a tag infNFe, procura a tag infEvento except IndexError: try: tag = 'infEvento' ref = etree.SubElement( siginfo, 'Reference', URI='#' + xml.findall('infEvento')[0].attrib['Id']) # Caso nao tenha a tag infNFe, procura a tag inutNFe except IndexError: tag = 'infInut' ref = etree.SubElement( siginfo, 'Reference', URI='#' + xml.findall('infInut')[0].attrib['Id']) trans = etree.SubElement(ref, 'Transforms') etree.SubElement( trans, 'Transform', Algorithm= 'http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement( trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') xml.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('testes.xml', 'w') as arquivo: arquivo.write( remover_acentos( etree.tostring(xml, encoding="unicode", pretty_print=False))) subprocess.check_call([ 'xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'testes.xml' ]) xml = etree.parse('funfa.xml').getroot() if retorna_string: return etree.tostring(xml, encoding="unicode", pretty_print=False) else: return xml except Exception as e: raise e
def assinarCancelar(self, xml, retorna_string=True): """ Método que assina o xml para cancelamento de NFS-e """ try: if self.autorizador == 'ginfes': xpath = 'CancelarNfseEnvio' tag = 'CancelarNfseEnvio' namespaces = { 'ns1': 'http://www.ginfes.com.br/servico_cancelar_nfse_envio', 'ns2': 'http://www.ginfes.com.br/tipos' } elif self.autorizador == 'betha': xpath = '/CancelarNfseEnvio/ns1:Pedido' tag = 'InfPedidoCancelamento' namespaces = { 'ns1': 'http://www.betha.com.br/e-nota-contribuinte-ws' } else: raise Exception('Autorizador não encontrado!') xml = etree.fromstring(xml) # No raiz do XML de saida raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement( siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Tenta achar a tag informada no xpath if tag == 'InfPedidoCancelamento': ref = etree.SubElement( siginfo, 'Reference', URI='#' + xml.xpath('.//ns1:' + tag, namespaces=namespaces)[0].attrib['Id']) # ginfes não tem id no cancelamento v2 else: ref = etree.SubElement(siginfo, 'Reference', URI='') trans = etree.SubElement(ref, 'Transforms') etree.SubElement( trans, 'Transform', Algorithm= 'http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement( trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') if tag == 'InfPedidoCancelamento': xml = xml.xpath(xpath, namespaces=namespaces)[0] # ginfes só possui a tag root else: xml.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: arquivo.write( remover_acentos( etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n', ''))) subprocess.check_call([ 'xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml' ]) if retorna_string: return open('funfa.xml', 'r').read() else: return etree.parse('funfa.xml').getroot() except Exception as e: raise e
def assinarNfse(self, xml, retorna_string=True): "Assina NFS-e" try: # define variaveis de acordo com autorizador if self.autorizador == 'ginfes': xpath = './/ns2:InfRps' tag = 'InfRps' elif self.autorizador == 'betha': xpath = './/ns1:InfDeclaracaoPrestacaoServico' tag = 'InfDeclaracaoPrestacaoServico' else: raise Exception('Autorizador não encontrado!') xml = etree.fromstring(xml) # define namespaces, pega do proprio xml namespaces = xml.nsmap # No raiz do XML de saida raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') siginfo = etree.SubElement(raiz, 'SignedInfo') etree.SubElement( siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') # Tenta achar a tag ref = etree.SubElement( siginfo, 'Reference', URI='#' + xml.xpath(xpath, namespaces=namespaces)[0].attrib['Id']) trans = etree.SubElement(ref, 'Transforms') etree.SubElement( trans, 'Transform', Algorithm= 'http://www.w3.org/2000/09/xmldsig#enveloped-signature') etree.SubElement( trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') etree.SubElement( ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') etree.SubElement(ref, 'DigestValue') etree.SubElement(raiz, 'SignatureValue') keyinfo = etree.SubElement(raiz, 'KeyInfo') etree.SubElement(keyinfo, 'X509Data') rps = xml.xpath(xpath + '/..', namespaces=namespaces)[0] rps.append(raiz) # Escreve no arquivo depois de remover caracteres especiais e parse string with open('nfse.xml', 'w') as arquivo: texto = remover_acentos( etree.tostring(xml, encoding="unicode", pretty_print=False)) # se for tag do Betha if tag == 'InfDeclaracaoPrestacaoServico': texto = texto.replace('ns1:', '').replace(':ns1', '') arquivo.write(texto) subprocess.check_call([ 'xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'nfse.xml', '--id-attr:Id', tag, 'nfse.xml' ]) if retorna_string: return open('nfse.xml', 'r').read() else: return etree.parse('nfse.xml').getroot() except Exception as e: raise e
def verificar_arquivo(self, caminho_arquivo): # Carrega o XML do arquivo raiz = etree.parse(caminho_arquivo) return self.verificar_etree(raiz)