我找到了Xades Signature for Python GitHub。我的计划是将Xades-EPES签名应用于XML文件。根据GitHub的工作,它能够执行此过程,但我无法执行此操作。
test_xades.py
有两种方法。尝试运行该错误消息。好吧,问题在于我不确定该库是否可以签署Xades-EPES或如何实现。
提前谢谢
代码:
import unittest
from datetime import datetime
from os import path
from OpenSSL import crypto
import xmlsig
from xades import XAdESContext, template, utils, ObjectIdentifier
from xades.policy import GenericPolicyId, ImpliedPolicy
from basex import parse_xml, BASE_DIR
class TestXadesSignature(unittest.TestCase):
def test_verify(self):
root = parse_xml('data/sample.xml')
sign = root.xpath(
'//ds:Signature', namespaces={'ds': xmlsig.constants.DSigNs}
)[0]
ctx = XAdESContext()
ctx.verify(sign)
def test_sign(self):
root = parse_xml('data/unsigned-sample.xml')
sign = root.xpath(
'//ds:Signature', namespaces={'ds': xmlsig.constants.DSigNs}
)[0]
policy = GenericPolicyId(
'http://www.facturae.es/politica_de_firma_formato_facturae/'
'politica_de_firma_formato_facturae_v3_1.pdf',
u"Politica de Firma FacturaE v3.1",
xmlsig.constants.TransformSha1
)
ctx = XAdESContext(policy)
with open(path.join(BASE_DIR, "data/keyStore.p12"), "rb") as key_file:
ctx.load_pkcs12(crypto.load_pkcs12(key_file.read()))
ctx.sign(sign)
ctx.verify(sign)
def test_create(self):
root = parse_xml('data/free-sample.xml')
signature = xmlsig.template.create(
xmlsig.constants.TransformInclC14N,
xmlsig.constants.TransformRsaSha1,
"Signature"
)
signature_id = utils.get_unique_id()
ref = xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha1, uri="", name="REF"
)
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha1, uri="#KI"
)
xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha1, uri="#" + signature_id
)
ki = xmlsig.template.ensure_key_info(signature, name='KI')
data = xmlsig.template.add_x509_data(ki)
xmlsig.template.x509_data_add_certificate(data)
serial = xmlsig.template.x509_data_add_issuer_serial(data)
xmlsig.template.x509_issuer_serial_add_issuer_name(serial)
xmlsig.template.x509_issuer_serial_add_serial_number(serial)
xmlsig.template.add_key_value(ki)
qualifying = template.create_qualifying_properties(
signature, name=utils.get_unique_id()
)
props = template.create_signed_properties(
qualifying, name=signature_id
)
template.add_claimed_role(props, "Supp2")
template.add_production_place(props, city='Madrid')
template.add_production_place(
props, state='BCN', postal_code='08000', country='ES')
template.add_claimed_role(props, "Supp")
policy = GenericPolicyId(
'http://www.facturae.es/politica_de_firma_formato_facturae/'
'politica_de_firma_formato_facturae_v3_1.pdf',
u"Politica de Firma FacturaE v3.1",
xmlsig.constants.TransformSha1
)
root.append(signature)
ctx = XAdESContext(policy)
with open(path.join(BASE_DIR, "data/keyStore.p12"), "rb") as key_file:
ctx.load_pkcs12(crypto.load_pkcs12(key_file.read()))
ctx.sign(signature)
ctx.verify(signature)
def test_create_2(self):
root = parse_xml('data/free-sample.xml')
signature = xmlsig.template.create(
xmlsig.constants.TransformInclC14N,
xmlsig.constants.TransformRsaSha1,
"Signature"
)
ref = xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha1, uri="", name="R1"
)
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha1, uri="#KI", name="RKI"
)
ki = xmlsig.template.ensure_key_info(signature, name='KI')
data = xmlsig.template.add_x509_data(ki)
xmlsig.template.x509_data_add_certificate(data)
serial = xmlsig.template.x509_data_add_issuer_serial(data)
xmlsig.template.x509_issuer_serial_add_issuer_name(serial)
xmlsig.template.x509_issuer_serial_add_serial_number(serial)
xmlsig.template.add_key_value(ki)
qualifying = template.create_qualifying_properties(signature)
utils.ensure_id(qualifying)
utils.ensure_id(qualifying)
props = template.create_signed_properties(
qualifying, datetime=datetime.now()
)
template.add_claimed_role(props, "Supp")
signed_do = template.ensure_signed_data_object_properties(props)
template.add_data_object_format(
signed_do,
"#R1",
identifier=ObjectIdentifier("Idenfitier0", "Description")
)
template.add_commitment_type_indication(
signed_do,
ObjectIdentifier("Idenfitier0", "Description"),
qualifiers_type=["Tipo"]
)
template.add_commitment_type_indication(
signed_do,
ObjectIdentifier("Idenfitier1", references=["#R1"]),
references=["#R1"]
)
template.add_data_object_format(
signed_do,
"#RKI",
description="Desc",
mime_type="application/xml",
encoding='UTF-8'
)
root.append(signature)
ctx = XAdESContext(ImpliedPolicy(xmlsig.constants.TransformSha1))
with open(path.join(BASE_DIR, "data/keyStore.p12"), "rb") as key_file:
ctx.load_pkcs12(crypto.load_pkcs12(key_file.read()))
ctx.sign(signature)
from lxml import etree
print(etree.tostring(root))
ctx.verify(signature)
x= TestXadesSignature()
x.test_create()
x.test_create_2()
回溯:
Exception has occurred: StopIteration
exception: no description
File "/home/sergio/Escritorio/PROYECTOSMAY2018/haciendaPython/src/lxml/lxml.etree.pyx", line 2821, in lxml.etree._ElementMatchIterator.__next__ (src/lxml/lxml.etree.c:75265)
File "/home/sergio/Escritorio/PROYECTOSMAY2018/haciendaPython/haciendaCode/pythoncorella/test/test_xades.py", line 50, in test_create
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
File "/home/sergio/Escritorio/PROYECTOSMAY2018/haciendaPython/haciendaCode/pythoncorella/test/test_xades.py", line 150, in <module>
x.test_create()
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/usr/lib/python3.6/runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "/usr/lib/python3.6/runpy.py", line 263, in run_path
pkg_name=pkg_name, script_name=fname)
答案 0 :(得分:2)
使用这个导入
import xmlsig
from lxml import etree
from OpenSSL import crypto
from xades import XAdESContext, template, utils
from xades.policy import GenericPolicyId
这是全球
POLICY_ENDPOINT = "politicadefirma/v2/politicadefirmav2.pdf"
SIGN_POLICY = f"http://facturaelectronica.dian.gov.co/{POLICY_ENDPOINT}"
CERTICAMARA_PFX = os.environ.get(
'CERTICAMARA_PFX',
'/path/to/certificate.pfx')
需要解析要签名的xml文件
parsed_file = etree.parse(file_path).getroot()
使用相应的转换内容创建签名模板
signature = xmlsig.template.create(
xmlsig.constants.TransformInclC14N,
xmlsig.constants.TransformRsaSha256,
"Signature",
)
创建一个 uuid 和对签名的引用
signature_id = utils.get_unique_id()
ref = xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha256, uri="", name="REF"
)
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha256, uri="#" + signature_id
)
xmlsig.template.add_reference(
signature, xmlsig.constants.TransformSha256, uri="#" + signature_id
)
ki = xmlsig.template.ensure_key_info(signature, name="KI")
data = xmlsig.template.add_x509_data(ki)
xmlsig.template.x509_data_add_certificate(data)
serial = xmlsig.template.x509_data_add_issuer_serial(data)
xmlsig.template.x509_issuer_serial_add_issuer_name(serial)
xmlsig.template.x509_issuer_serial_add_serial_number(serial)
xmlsig.template.add_key_value(ki)
qualifying = template.create_qualifying_properties(
signature, name=utils.get_unique_id(), etsi='xades'
)
props = template.create_signed_properties(qualifying, name=signature_id)
# Additional data for signature
template.add_claimed_role(props, "Supp2")
template.add_production_place(props, city="Bogotá Colombia")
template.add_production_place(
props, state="BCN", postal_code="08000", country="CO"
)
template.add_claimed_role(props, "SNE")
policy = GenericPolicyId(
SIGN_POLICY,
u"Política de firma para facturas"
" electrónicas de la República de Colombia",
xmlsig.constants.TransformSha256,
)
parsed_file.append(signature)
with open(CERTICAMARA_ANDES_PFX, "rb") as key_file:
certificate = crypto.load_pkcs12(key_file.read(), 'filepassword')
ctx = XAdESContext(
policy,
certificate.get_certificate().to_cryptography(),
)
ctx.load_pkcs12(certificate)
ctx.sign(signature)
parsed_file[0][position][0].append(signature)
et = etree.ElementTree(parsed_file)
nfs_name = 'Name of the signed file'
et.write(nfs_name, pretty_print=True,
encoding='utf-8', xml_declaration=True)
我在我的国家的一个电子发票签名项目中使用了这个,考虑到 Enric Tobella 的源代码与包相比是领先的。使用源代码,您可以添加多个证书,而软件包只允许您使用一个,这是我发现的唯一区别。