XML SOAP 主体的签名

XML Signature of SOAP Body

我正在为需要 soap:body 签名的 WS 实现客户端。该应用程序是用 Go 编写的,所以我宁愿避免链接到 C。

最大的问题是:如何计算SHA256?摘要算法的输入应该是什么?我假设“/CJj9686ARgbV/YmDrr+1yhcaJuXu022cADK/M8efQs=”是稍后签名的 SHA256 结果。我尝试了规范化 XML 的多种变体,但其中 none 导致了此哈希。

这是一个正确的 SOAP 消息示例

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                       soap:mustUnderstand="1">
            <wsse:BinarySecurityToken
                    EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
                    ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
                    wsu:Id="X509-16FE2A6FC1AFE42BE9146412186273511">
                MIID7DCCAtSgAwIBAgIEAQAABDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJDWjEaMBgGA1UEAwwRR0ZSIEVFVCB0ZXN0IENBIDExLTArBgNVBAoMJEdlbmVyw6FsbsOtIGZpbmFuxI1uw60gxZllZGl0ZWxzdHbDrTAeFw0xNjA1MTkxMjQ4MjVaFw0xODA1MTkxMjQ4MjVaMFQxCzAJBgNVBAYTAkNaMRMwEQYDVQQDDApDWjAwMDAwMDE5MRowGAYDVQQKDBFQcsOhdm5pY2vDoSBvc29iYTEUMBIGA1UEBRMLVDAwMDAwMDAwMDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFCIfnLl3YjNyxM3y2FAVovKQMetfyyj/lfLY3DoN1z/8gaVRfcqTZbwh9Btg0HafSmrWBvfgjEC/pG9HNawYZ9nPE+WIP9bXkoOfDTmmVtX4n6OLi2Di+U7+FmPJzykV0ujsOsfcGnQ0f63xZYoGJIwLJuz3gmAF//DfnOeTT7OUZeOKobBSYkQOKv1j05QqQZ7HP+5oq7+hNylFrjuEi5OAeVgJAYScE4COvcpqPKpb7OeR9f78knYFffg5zp/6bi6qkP5uGYEuuQvbW1mATjoqbAWz8c7HNA56uNFlz8V+z9bL0f/xwQjgy4d+5qelTX46tq0vJ2XM9dJaF8ytJAgMBAAGjgcEwgb4wHgYDVR0RBBcwFYETZXBvZHBvcmFAZnMubWZjci5jejAfBgNVHSMEGDAWgBR6WvwNy+w2pg3aaRlmjJvvgsOpNDAdBgNVHQ4EFgQU8oKPLNlNY0/h8jWEmz3EZ1O3bBMwTAYDVR0gBEUwQzBBBgpghkgBZQMCATACMDMwMQYIKwYBBQUHAgIwJRojVGVudG8gY2VydGlmaWthdCBKRSBQT1VaRSBURVNUT1ZBQ0kwDgYDVR0PAQH/BAQDAgbAMA0GCSqGSIb3DQEBCwUAA4IBAQBVulEYg6noEHqAW3DfNWLvW9XdHFZQj3L5EE3Nwdd0CtMZm4/RZ/CvSENkk+GWv0YCUqHPJzhcKs0NETMKW7L6CI+hY17rD5SHhuoCYzSMlcuMA6gZJr8wIxSWerQrvuZ4uAUMistWG9cgwETZjkGU9JK+H98wdAm2co7WaRweDsNx04aSXagUMDAmRY/jNe7c8/HvwIdnXftbIl56wbYlYiCIG2qS+6lVO+09EIEP40kz1PXlqFZbPLCSlT2YsYiqizfkCX/Ka+AebJykAQ3pOqD6PQ+Y2AMAIRX8AypcN6Yj9p+oof9rda8boA8rA7wwzlJs/+ipWt2ceqPPuL9x
            </wsse:BinarySecurityToken>
            <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-16FE2A6FC1AFE42BE9146412186273615">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                        <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap"/>
                    </ds:CanonicalizationMethod>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                    <ds:Reference URI="#id-16FE2A6FC1AFE42BE9146412186273614">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                                <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
                                                        PrefixList=""/>
                            </ds:Transform>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                        <ds:DigestValue>/CJj9686ARgbV/YmDrr+1yhcaJuXu022cADK/M8efQs=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>
                    Ii+W0EB2V6GJo4jMGwK1HCRdt6+r9TkgfhXyAuY8FNCXhPOtfoUi/Bw31U4Hm7SLscM/8klrQI3Z2vSfdNe3oDi1cm2Qouv1sOBK17VSg/IgKN92BC8kUaoF5W5ZBEcZr0WHjDWasSYEerZQ3Q+ZIJzt6cbS+cLZfQkLFg1UDOi5qLUkWE1pQ9AVYCvwrOFj/hFQx5koQTpigyG/DPlyoh2xOh/DAh6U/P5p+IiQwwCMdo1Rh2czUVpRCr3Cnz97AlQ8G6IGAtWNykXorVYZ1tGnXEaRngzjsn5RE/zCcRkqRpFaiEQuYly1I6YtFOEYIPXskE5oMZkCLINebu1Law==
                </ds:SignatureValue>
                <ds:KeyInfo Id="KI-16FE2A6FC1AFE42BE9146412186273512">
                    <wsse:SecurityTokenReference
                            xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                            wsu:Id="STR-16FE2A6FC1AFE42BE9146412186273513">
                        <wsse:Reference URI="#X509-16FE2A6FC1AFE42BE9146412186273511"
                                        ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </ds:Signature>
        </wsse:Security>
    </SOAP-ENV:Header>
    <soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
               wsu:Id="id-16FE2A6FC1AFE42BE9146412186273614">
        <Trzba xmlns="http://fs.mfcr.cz/eet/schema/v2">
            <Hlavicka dat_odesl="2016-09-19T19:06:37+01:00" prvni_zaslani="false"
                      uuid_zpravy="9edeb22b-4234-4047-869c-3a76f86c20d3"/>
            <Data celk_trzba="34113.00" cerp_zuct="679.00" cest_sluz="5460.00" dan1="-172.39" dan2="-530.73"
                  dan3="975.65" dat_trzby="2016-01-05T00:30:12+01:00" dic_popl="CZ00000019" id_pokl="/5546/RO24"
                  id_provoz="273" porad_cis="0/6460/ZQ42" pouzit_zboz1="784.00" pouzit_zboz2="967.00"
                  pouzit_zboz3="189.00" rezim="0" urceno_cerp_zuct="324.00" zakl_dan1="-820.92" zakl_dan2="-3538.20"
                  zakl_dan3="9756.46" zakl_nepodl_dph="3036.00"/>
            <KontrolniKody>
                <pkp cipher="RSA2048" digest="SHA256" encoding="base64">
                    W7UlA4hXNsDLvCj/eeRAYeOAsNsgMSdltcJNIW98KQRsfspTMW0Lr/OGQgRHZfO5KjolZgzN3k9mgzrVoX2+N90fCNEnOri2kjrW5vzTgMK6OZ9IryAEg0xFZjjjCQ0qKsQsVi8OLQOn3ZnN/BUGG2SIduER+iIOrhfOmes7OXaa5/2jQSfPTHZHZ/Bxhqld3gL4PHvd7sevZYUupHpE1fM7Uw1+lu8i1YOdghZoMyOfKw7FcqvRJpHrW/JZL5Dr5iCgu5ClmhZrb3hZavsxlDG7P2cUhSQgmEVTxJ2n38q/Cf91KE8e52SODN4Q8BfncXpmtkQ7Go3KsRsY3xN7xg==
                </pkp>
                <bkp digest="SHA1" encoding="base16">1F1A2D90-4EAD34A8-411CFB0B-EB17616E-B2CE8114</bkp>
            </KontrolniKody>
        </Trzba>
    </soap:Body>
</soap:Envelope>

像这样计算 sha256

import (
"crypto/sha256"

)

var slice = []byte("test")

return sha256.Sum256(slice)

终于,我找到了获取所有值的方法。

  1. 规范化 中定义的 XML 元素。在本例中,它是 元素。规范化仅添加 soap 名称空间并添加结束标记。我在 Go 中生成这些并且 Go 从不生成自关闭标签。
  2. 根据规范化 的字符串表示计算散列,因为它将在请求中发送。
  3. 将计算出的摘要添加到相应中。
  4. 规范化 并计算它的哈希值。
  5. 签署此散列并将值添加到

我知道这不是通用方法,但它应该适合我。 C14N 不是必需的,因为如果您注意属性顺序并手动添加命名空间,Go 可以产生相同的结果。

参考 XML 示例 CZ00000019.valid.v3.xml(捷克财政当局 EET)规范化的 SignedInfo 是:

var signedinfoCanon 
= '<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
+ '<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">'
+ '<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap"></ec:InclusiveNamespaces>'
+ '</ds:CanonicalizationMethod>'
+ '<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></ds:SignatureMethod>'
+ '<ds:Reference URI="#id-A72D6FD4C41B1F545F14700558808234">'
+ '<ds:Transforms>'
+ '<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">'
+ '<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""></ec:InclusiveNamespaces>'
+ '</ds:Transform>'
+ '</ds:Transforms>'
+ '<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod>'
+ '<ds:DigestValue>4hn06sSS2yurIiUmWaV36JQJZrwbWf36sG9bOHH/ycM=</ds:DigestValue>'
+ '</ds:Reference>'
+ '</ds:SignedInfo>'