簡體   English   中英

如何用xmlib2規范化消化SOAP的Body

[英]How to canonicalize and digest the Body of SOAP with xmlib2

我正在嘗試手動簽署 SOAP 請求。 在我的 cpp 應用程序中使用 libxml2,我可以使用 xmlC14NDocDumpMemory function 和 xmlNodeSetPtr 作為 null 參數規范化和消化整個 883812976388 soap 文檔。 然而,對於實際簽名,我只需要專門處理 SOAP 的正文。

   xmlChar* canon;

    int canonLength = xmlC14NDocDumpMemory(
        doc,
        nullptr,
        xmlC14NMode::XML_C14N_EXCLUSIVE_1_0,
        nullptr,
        1,
        &canon
    );

std::string canonizedString(reinterpret_cast<const char*>(canon), canonLength);

std::cout << "canonized string:\n" << canonizedString << std::endl;

//freeing the original parsed file:
xmlFreeDoc(doc);

//digesting the value:
const EVP_MD* md = EVP_sha1(); // algorithm

unsigned char digest_value[EVP_MAX_MD_SIZE]; //the digest result value
unsigned int dv_length; //the digest result length


EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); //create msg digest context
EVP_DigestInit_ex(mdctx, md, NULL);  // Initialise the context (engine null value?)
EVP_DigestUpdate(mdctx, canon, canonLength); //digesting
EVP_DigestFinal_ex(mdctx, digest_value, &dv_length); //finalizing
EVP_MD_CTX_free(mdctx); //free the context


char* base64convert;
size_t base64convertLength;

base64::Encode(
    reinterpret_cast<const char*>(digest_value),
    dv_length,
    &base64convert,
    &base64convertLength);

std::string digest64(base64convert, base64convertLength);

std::cout << "\ndigest value:\n" << digest64;

示例 SOAP:

<?xml version="1.0" encoding="UTF-8"?>
<e:Envelope xmlns:e="http://schemas.xmlsoap.org/soap/envelope/">
    <e:Header/>
    <e:Body>
        <!-- doctor-E,EGN:XXXXXXXXXX -->
        <ws:hbIn xmlns:ws="http://pis.technologica.com/ws/">
            <ws:egn>XXXXXXXXXX</ws:egn>
            <ws:date>2015-06-11</ws:date>
        </ws:hbIn>
    </e:Body>
</e:Envelope>

符號示例的結果:

    <e:Envelope xmlns:e="http://schemas.xmlsoap.org/soap/envelope/">
        <e:Header>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
                <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
                <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <Reference URI="#signedContent">
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>                          
<DigestValue>93BoBU73Y0Efm1rarqzUGw5x4SU=</DigestValue>
                    </Reference>
            </SignedInfo>
                <SignatureValue>jQGU7xsoSVGx/a......</SignatureValue>
                    <KeyInfo>
                        <X509Data>
                            <X509Certificate>MIICjzCCAfi......</X509Certificate>
                        </X509Data>
                    </KeyInfo>
                </Signature>
            </e:Header>
        <e:Body id="signedContent">
            <!-- doctor-E,EGN:XXXXXXXXXX -->
            <ws:hbIn xmlns:ws="http://pis.technologica.com/ws/">
                <ws:egn>XXXXXXXXXX</ws:egn>
                <ws:date>2015-06-11</ws:date>
            </ws:hbIn>
        </e:Body>
    </e:Envelope>

所以問題是如何獲得 93BoBU73Y0Efm1rarqzUGw5x4SU= 值? 我注意到簽名的 soap 正文具有 URI id“signedContent”。 我不確定這個 URI 是在消化之前還是之后插入的(如果之前插入它可能會改變整個 hash)。

我對任何在這里絆倒的人的建議是——不要試圖自己規范化、消化和簽名。 使用 xmlsec。 盡管構建起來很麻煩(我在 Windows 上)並且文檔幾乎不存在,但它完成了工作。 可以在此處找到最終答案: 使用 xmlsec 對 XML 的一部分進行簽名

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM