Python xmlsec XML 签名值不匹配
Python xmlsec XML Signature Value mismatch
我是 xml 签名的新手,目前我正在使用 xmlsec 生成签名的 xml。我对示例代码做了一些修改:
from lxml import etree
import xmlsec
parser = etree.XMLParser(remove_blank_text=True)
template = etree.parse('unsigned.xml', parser).getroot()
signature_node = xmlsec.tree.find_node(template, xmlsec.constants.NodeSignature)
ctx = xmlsec.SignatureContext()
key = xmlsec.Key.from_file('keys/private_key.pem', xmlsec.constants.KeyDataFormatPem)
ctx.key = key
sig_ = ctx.sign(signature_node)
formated = etree.tostring(template)
with open('signed_test.xml', 'wb') as the_file:
the_file.write(formated)
现在我已经签署了 XML,我正试图从这里了解这些值是在何处或如何生成的。我正在关注 this 以了解上下文。我能够验证 DigestValue
,现在我正在尝试获取 SignatureValue
。从 link 和 Whosebug 中的其他一些问题,我只需要:
- 将整个
SignedInfo
元素规范化
- 哈希结果
- 对哈希签名
为了得到签名值。我正在使用 lxml
:
规范 SignedInfo
元素
from lxml import etree
parser = etree.XMLParser(remove_blank_text=True)
xmlTree = etree.parse('signed_info.xml', parser)
root = xmlTree.getroot()
formated = etree.tostring(root, method='c14n', exclusive=True)
# Write to file
with open('canon_sinfo.xml', 'wb') as the_file:
the_file.write(formated)
有关信息,以下是结果 SignedInfo
:
<SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod><Reference URI="#obj"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#base64"></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod><DigestValue>izbIdQ4tSAg6VKGpr1zd6kU9QpVQi/Bcwxjxu/k2oKk=</DigestValue></Reference></SignedInfo>
我正在使用 cryptography 尝试生成 SignatureValue
但是,我无法获得与 xml 秒生成的结果相同的结果。
这是我这样做的代码片段:
sign_info = '''String of the Sign Info'''
digest_sinfo = hashes.Hash(hashes.SHA256(), backend=default_backend())
digest_sinfo.update(bytes(sign_info, 'utf-8'))
digested_sinfo = digest_sinfo.finalize()
# Load private_key here...
# Sign the message
signature_1v15 = private_key.sign(
digested_sinfo,
padding.PKCS1v15(),
hashes.SHA256()
)
我也尝试将 SignedInfo
加载到一个单独的文件中,但是我仍然得到不匹配的 SignatureValue。我该如何实现?
您的问题是您进行了两次哈希处理。 sign()
函数为您进行哈希处理,因此您可以跳过中间部分。
只需使用规范化的 SignedInfo 元素调用 sign()
:
signature_1v15 = private_key.sign(
sign_info,
padding.PKCS1v15(),
hashes.SHA256()
)
我是 xml 签名的新手,目前我正在使用 xmlsec 生成签名的 xml。我对示例代码做了一些修改:
from lxml import etree
import xmlsec
parser = etree.XMLParser(remove_blank_text=True)
template = etree.parse('unsigned.xml', parser).getroot()
signature_node = xmlsec.tree.find_node(template, xmlsec.constants.NodeSignature)
ctx = xmlsec.SignatureContext()
key = xmlsec.Key.from_file('keys/private_key.pem', xmlsec.constants.KeyDataFormatPem)
ctx.key = key
sig_ = ctx.sign(signature_node)
formated = etree.tostring(template)
with open('signed_test.xml', 'wb') as the_file:
the_file.write(formated)
现在我已经签署了 XML,我正试图从这里了解这些值是在何处或如何生成的。我正在关注 this 以了解上下文。我能够验证 DigestValue
,现在我正在尝试获取 SignatureValue
。从 link 和 Whosebug 中的其他一些问题,我只需要:
- 将整个
SignedInfo
元素规范化 - 哈希结果
- 对哈希签名
为了得到签名值。我正在使用 lxml
:
SignedInfo
元素
from lxml import etree
parser = etree.XMLParser(remove_blank_text=True)
xmlTree = etree.parse('signed_info.xml', parser)
root = xmlTree.getroot()
formated = etree.tostring(root, method='c14n', exclusive=True)
# Write to file
with open('canon_sinfo.xml', 'wb') as the_file:
the_file.write(formated)
有关信息,以下是结果 SignedInfo
:
<SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod><Reference URI="#obj"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#base64"></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod><DigestValue>izbIdQ4tSAg6VKGpr1zd6kU9QpVQi/Bcwxjxu/k2oKk=</DigestValue></Reference></SignedInfo>
我正在使用 cryptography 尝试生成 SignatureValue
但是,我无法获得与 xml 秒生成的结果相同的结果。
这是我这样做的代码片段:
sign_info = '''String of the Sign Info'''
digest_sinfo = hashes.Hash(hashes.SHA256(), backend=default_backend())
digest_sinfo.update(bytes(sign_info, 'utf-8'))
digested_sinfo = digest_sinfo.finalize()
# Load private_key here...
# Sign the message
signature_1v15 = private_key.sign(
digested_sinfo,
padding.PKCS1v15(),
hashes.SHA256()
)
我也尝试将 SignedInfo
加载到一个单独的文件中,但是我仍然得到不匹配的 SignatureValue。我该如何实现?
您的问题是您进行了两次哈希处理。 sign()
函数为您进行哈希处理,因此您可以跳过中间部分。
只需使用规范化的 SignedInfo 元素调用 sign()
:
signature_1v15 = private_key.sign(
sign_info,
padding.PKCS1v15(),
hashes.SHA256()
)