从 python 中的 SOAP 请求复制/验证 XMLDSig

Replicating / verifying XMLDSig from a SOAP request in python

我正在尝试使用 WS-Security 从 gSOAP 网络服务复制 XMLDSig,但签名永远不匹配。该服务使用 rsa-sha1,我可以访问 public 和私钥。

我正在通过正则表达式获取元素的字节串,包括尾随制表符 (b'\t'),因此它与原始的逐字节相同,我正在尝试使用相同的私钥(或者,我尝试使用 public 密钥验证签名),但无济于事。

目前,我正在尝试删除制表符 (b'\t'),以便它与 XML 根齐平:

def extractSigInfFromHttp(data):
    f = io.BytesIO(data)
    root = etree.parse(f)
    data = c14n(nodes=root, algorithm='http://www.w3.org/2001/10/xml-exc-c14n#')
    filtered = re.search(b'<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">\n([\s\S]+)</ds:SignedInfo>', data)
    if(filtered):
        sig = filtered.group(1)
    newsig = re.sub(b'\t\t\t\t', b'', sig)
    return newsig + b'</ds:SignedInfo>'

正如你在代码中看到的,我在签名/验证之前也做了c14n。

但是签名从不匹配/验证...谁能告诉我 gSOAP WSS 或 WSS 通常以哪种形式处理元素?我在网上找到的 XMLDSig 示例总是只显示元素作为根元素,或者从不显示具体消化的内容。

联系 gSOAP 支持后,我被告知要使用未缩进的 XML,因为缩进的 XML 的行为几乎不可预测。

此外,我最终使用 signxml.XMLVerifier().verify 并在 signedInfo 变量得到验证之前获取它。基本上,这里的方法是在 xml 上构建一个 etree 并在那里提取 SignedInfo 元素。不知道它与字节(子)字符串有何不同,但这使得 M2Crypto 验证有效。