xml 针对自定义 CA 的签名验证
xml signature verification against custom CA
我需要验证 POST 请求的答复中包含的 xml 签名。
签名定义为:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>htti3M3ikfm2RooDTNo3Kv7g0K2ongShUfCDUAWpytc=</DigestValue>
</Reference>
</SignedInfo>
并且反对自定义 CA。
我无法更改答案(它是由国家机构发布的),而且我根据据称用于签名的证书进行验证的所有尝试都导致了错误。
我的一个尝试是使用以下简短的测试程序:
#!/usr/bin/python3
import signxml
cf = 'certificate.cer'
with open(cf, 'r') as fi:
cer = fi.read()
ver = signxml.XMLVerifier()
f = 'response.xml'
with open(f, 'rb') as fi:
xml = fi.read()
try:
vd = ver.verify(xml, x509_cert=cer)
print('OK')
except signxml.exceptions.InvalidSignature as e:
print(e)
这导致:
Signature verification failed: wrong signature length
其他变体有不同的错误,包括:
Signature verification failed: invalid padding
和:
unable to get local issuer certificate
我是一名经验丰富的程序员,但不是密码学专家,所以我很可能忘记了一些琐碎的事情(对知识渊博的人来说)。
请给我指明正确的方向。
注意::如果需要,我可以提供完整的(失败的)示例,因为 certificate/answer 不是 "secret"。
Question: I need to verify an xml signature contained in the answer to a POST request.
按照文档 SignXML: XML Signature in Python 中的示例进行操作:
SignXML uses the ElementTree API (also supported by lxml) to work with XML data.
from signxml import XMLSigner, XMLVerifier
from xml.etree import ElementTree
cert = open("example.pem").read()
key = open("example.key").read()
xml = ElementTree.parse(file_name) #(data_to_sign)
signed_xml = XMLSigner().sign(xml, key=key, cert=cert)
result = XMLVerifier().verify(signed_xml)
XMLVerifier().verify(...)
验证数据中提供的 XML 签名和 return 由签名签名的 XML 节点,或者如果签名无效则引发异常。
class signxml.VerifyResult
The results of a verification return the signed data, the signed xml and the signature xml
注意:必读See what is signed and Establish trust!
相关:
不幸的是,事情总是比预期的要复杂一些。
@stovfl 的回答完全没有抓住重点:我需要针对非标准 CA 进行验证。
我已经在努力使用 sigxml
包,我必须克服以下问题:
sigxml
对普通 xml.etree
不起作用(对我来说);我不得不使用具有不同语法的 lxml.etree
。
普通 pip3 install sigxml
安装的 sigxml
会出现弃用错误;我必须使用 pip3 install git+https://github.com/XML-Security/signxml.git
. 从 github 获取最新的(未标记的主)
sigxml
站点上的示例完全忽略 python3 str
与 bytes
的问题。
- 用于签署我用于签署传出消息的证书的 CA 机构与用于签署响应的 CA 机构不同(我无法更改此设置!)。
虽然这个故事有一个 Happy Ending。
以下测试程序有效(对我而言):
from signxml import XMLSigner, XMLVerifier, InvalidCertificate
from lxml import etree
outCAroot = 'outCAroot.pem'
inCAroot = 'inCAroot.pem'
cert = open("example.pem").read().encode()
key = open("example.key").read().encode()
file_name = 'test.tosend'
resp_name = 'test.rsp'
xml = etree.parse(file_name) # (data_to_sign)
signer = XMLSigner(c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315')
signed_xml = signer.sign(xml, key=key, cert=cert)
try:
result = XMLVerifier().verify(signed_xml, ca_pem_file=outCAroot)
except InvalidCertificate as e:
print(e)
else:
print('outgoing signature Ok.')
# here I send signed_xml to remote server and get the response (NO ERRORS!)
answer_xml = etree.parse(resp_name) # (signed answer)
try:
result = XMLVerifier().verify(answer_xml, ca_pem_file=inCAroot)
except InvalidCertificate as e:
print(e)
else:
print('incoming signature Ok.')
print('===================')
print(result.signed_data.decode())
print('===================')
我希望这对处于(或将处于)我处境的人有所帮助。
我需要验证 POST 请求的答复中包含的 xml 签名。
签名定义为:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>htti3M3ikfm2RooDTNo3Kv7g0K2ongShUfCDUAWpytc=</DigestValue>
</Reference>
</SignedInfo>
并且反对自定义 CA。
我无法更改答案(它是由国家机构发布的),而且我根据据称用于签名的证书进行验证的所有尝试都导致了错误。
我的一个尝试是使用以下简短的测试程序:
#!/usr/bin/python3
import signxml
cf = 'certificate.cer'
with open(cf, 'r') as fi:
cer = fi.read()
ver = signxml.XMLVerifier()
f = 'response.xml'
with open(f, 'rb') as fi:
xml = fi.read()
try:
vd = ver.verify(xml, x509_cert=cer)
print('OK')
except signxml.exceptions.InvalidSignature as e:
print(e)
这导致:
Signature verification failed: wrong signature length
其他变体有不同的错误,包括:
Signature verification failed: invalid padding
和:
unable to get local issuer certificate
我是一名经验丰富的程序员,但不是密码学专家,所以我很可能忘记了一些琐碎的事情(对知识渊博的人来说)。 请给我指明正确的方向。
注意::如果需要,我可以提供完整的(失败的)示例,因为 certificate/answer 不是 "secret"。
Question: I need to verify an xml signature contained in the answer to a POST request.
按照文档 SignXML: XML Signature in Python 中的示例进行操作:
SignXML uses the ElementTree API (also supported by lxml) to work with XML data.
from signxml import XMLSigner, XMLVerifier from xml.etree import ElementTree cert = open("example.pem").read() key = open("example.key").read() xml = ElementTree.parse(file_name) #(data_to_sign) signed_xml = XMLSigner().sign(xml, key=key, cert=cert) result = XMLVerifier().verify(signed_xml)
XMLVerifier().verify(...)
验证数据中提供的 XML 签名和 return 由签名签名的 XML 节点,或者如果签名无效则引发异常。
class signxml.VerifyResult
The results of a verification return the signed data, the signed xml and the signature xml
注意:必读See what is signed and Establish trust!
相关:
不幸的是,事情总是比预期的要复杂一些。
@stovfl 的回答完全没有抓住重点:我需要针对非标准 CA 进行验证。
我已经在努力使用 sigxml
包,我必须克服以下问题:
sigxml
对普通xml.etree
不起作用(对我来说);我不得不使用具有不同语法的lxml.etree
。
普通 sigxml
会出现弃用错误;我必须使用pip3 install git+https://github.com/XML-Security/signxml.git
. 从 github 获取最新的(未标记的主)
sigxml
站点上的示例完全忽略 python3str
与bytes
的问题。- 用于签署我用于签署传出消息的证书的 CA 机构与用于签署响应的 CA 机构不同(我无法更改此设置!)。
pip3 install sigxml
安装的 虽然这个故事有一个 Happy Ending。
以下测试程序有效(对我而言):
from signxml import XMLSigner, XMLVerifier, InvalidCertificate
from lxml import etree
outCAroot = 'outCAroot.pem'
inCAroot = 'inCAroot.pem'
cert = open("example.pem").read().encode()
key = open("example.key").read().encode()
file_name = 'test.tosend'
resp_name = 'test.rsp'
xml = etree.parse(file_name) # (data_to_sign)
signer = XMLSigner(c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315')
signed_xml = signer.sign(xml, key=key, cert=cert)
try:
result = XMLVerifier().verify(signed_xml, ca_pem_file=outCAroot)
except InvalidCertificate as e:
print(e)
else:
print('outgoing signature Ok.')
# here I send signed_xml to remote server and get the response (NO ERRORS!)
answer_xml = etree.parse(resp_name) # (signed answer)
try:
result = XMLVerifier().verify(answer_xml, ca_pem_file=inCAroot)
except InvalidCertificate as e:
print(e)
else:
print('incoming signature Ok.')
print('===================')
print(result.signed_data.decode())
print('===================')
我希望这对处于(或将处于)我处境的人有所帮助。