使用XMLSec库签名含指定URI的XML文档失败问题求助
XMLSec库签名含指定URI的XML文档失败问题求助
各位大佬好,我最近在用XMLSec库给NFCom格式的XML文件做签名,要求必须使用指定算法,同时要把<infNFCom>元素的Id属性作为引用的URI。但碰到一个特别诡异的问题:当我给add_reference方法的uri参数填值(格式是#{id_nfcom})时,文档完全签不了;可要是把这个URI留空,签名就能正常生成。我已经反复核对过Id属性的取值,确认和XML里的内容完全一致,实在搞不懂哪里出问题了。
示例ID:#NFCom43253123827184000163620017659731731076965182
下面是我的签名代码,重点是标记出来的那部分:
def assinar_xml(xml_tree, certificado_pem): root = xml_tree.getroot() inf_nfcom = root.find(".//{http://www.portalfiscal.inf.br/NFCom}infNFCom") if inf_nfcom is None: raise ValueError("Elemento <infNFCom> não encontrado no XML.") id_nfcom = inf_nfcom.get("Id") if not id_nfcom: raise ValueError("Atributo 'Id' não encontrado no elemento <infNFCom>.") signature = xmlsec.template.create( root, xmlsec.Transform.C14N, xmlsec.Transform.RSA_SHA1 ) # 就是这行代码,填了uri就签不了 ref = xmlsec.template.add_reference( signature, xmlsec.constants.TransformSha1, uri=f"#{id_nfcom}" ) xmlsec.template.add_transform(ref, xmlsec.Transform.ENVELOPED) xmlsec.template.add_transform(ref, xmlsec.Transform.C14N) key_info = xmlsec.template.ensure_key_info(signature) x509_data = xmlsec.template.add_x509_data(key_info) xmlsec.template.x509_data_add_certificate(x509_data) root.append(signature) ctx = xmlsec.SignatureContext() key = None try: key = xmlsec.Key.from_file(certificado_pem, xmlsec.constants.KeyDataFormatPem) print("Chave carregada com sucesso!") except Exception as e: print(f"Erro ao carregar a chave: {e}") if key is None: raise ValueError("A chave não foi carregada corretamente.") ctx.key = key ctx.sign(signature) return xml_tree
签名前的XML文档内容如下:
<NFCom xmlns="http://www.portalfiscal.inf.br/NFCom"> <infNFCom Id="NFCom43253123827184000163620017659731731076965182" versao="1.00"> <ide> <cUF>43</cUF> <tpAmb>2</tpAmb> <mod>62</mod> <serie>1</serie> <nNF>765973173</nNF> <cNF>7696518</cNF> <cDV>2</cDV> <dhEmi>2025-01-31T11:56:18-03:00</dhEmi> <tpEmis>1</tpEmis> <nSiteAutoriz>0</nSiteAutoriz> <cMunFG>3205309</cMunFG> <finNFCom>0</finNFCom> <tpFat>0</tpFat> <verProc>1.00</verProc> </ide> <emit> <CNPJ>23827184005463</CNPJ> <IE>9071339235</IE> <IEUFDest>321</IEUFDest> <CRT>1</CRT> <xNome>TELECOM LTDA ME</xNome> <xFant>Telecom</xFant> <enderEmit> <xLgr>AV. PRESIDENTE KENNEDY</xLgr> <nro>845</nro> <xBairro>Centro</xBairro> <cMun>4117909</cMun> <xMun>Palotina</xMun> <CEP>85950000</CEP> <UF>PR</UF> </enderEmit> </emit> <dest> <xNome>Cliente de Telecomunicações Ltda</xNome> <CNPJ>98765432000187</CNPJ> <indIEDest>1</indIEDest> <IE></IE> <IM>1</IM> <enderDest> <xLgr>Rua das Comunicações</xLgr> <nro>123</nro> <xBairro>Centro</xBairro> <cMun>3205309</cMun> <xMun>Vitória</xMun> <CEP>85950000</CEP> <UF>ES</UF> </enderDest> </dest> <assinante> <iCodAssinante>01</iCodAssinante> <tpAssinante>1</tpAssinante> <tpServUtil>4</tpServUtil> </assinante> <det nItem="1"> <prod> <cProd>001</cProd> <xProd>Serviço de Internet Banda Larga</xProd> <cClass>0400401</cClass> <CFOP>5303</CFOP> <uMed>2</uMed> <qFaturada>100.00</qFaturada> <vItem>100.00</vItem> <vProd>100.00</vProd> </prod> <imposto> <ICMS00> <CST>00</CST> <vBC>10.00</vBC> <pICMS>18.00</pICMS> <vICMS>1.80</vICMS> </ICMS00> </imposto> </det> <total> <vProd>100.00</vProd> <ICMSTot> <vBC>10.00</vBC> <vICMS>1.80</vICMS> <vICMSDeson>1.00</vICMSDeson> <vFCP>1.00</vFCP> </ICMSTot> <vCOFINS>1.00</vCOFINS> <vPIS>1.00</vPIS> <vFUNTTEL>1.00</vFUNTTEL> <vFUST>1.00</vFUST> <vRetTribTot> <vRetPIS>1.00</vRetPIS> <vRetCofins>1.00</vRetCofins> <vRetCSLL>1.00</vRetCSLL> <vIRRF>1.00</vIRRF> </vRetTribTot> <vDesc>0.00</vDesc> <vOutro>1.00</vOutro> <vNF>100.00</vNF> </total> </infNFCom> <infNFComSupl> <qrCodNFCom>http://dfe-portal.svrs.rs.gov.br/NFCom/QRCode?chNFCom=43120201234567890123456789012345678901234567&amp;tpAmb=2</qrCodNFCom> </infNFComSupl> </NFCom>
有没有大佬遇到过类似的问题?麻烦帮我看看哪里出错了,万分感谢!
备注:内容来源于stack exchange,提问作者Renan Akira Escribano
相关产品推荐
相关产品推荐

