1

Similarly to this question, I'm trying to calculate a document hash value for a SEPA container file. This is the container my code currently generates:

<?xml version="1.0" encoding="UTF-8"?>
<conxml xmlns="urn:conxml:xsd:container.nnn.003.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:conxml:xsd:container.nnn.003.02 container.nnn.003.02.xsd">
  <ContainerId>
    <SenderId>TEST</SenderId>
    <IdType>EBIC</IdType>
    <TimeStamp>090237000</TimeStamp>
  </ContainerId>
  <CreDtTm>2014-02-14T09:32:37+01:00</CreDtTm>
  <MsgPain008>
    <HashValue>942AB2F57DBAF6302EDC526472098DF38C540EB75E1913DAB0DF416D168C3253</HashValue>
    <HashAlgorithm>SHA256</HashAlgorithm>
    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.003.02">
      <CstmrDrctDbtInitn>
        <GrpHdr>
          <MsgId>testmsg-1</MsgId>
          <CreDtTm>2014-02-14T09:32:37+01:00</CreDtTm>
          <NbOfTxs>1</NbOfTxs>
          <CtrlSum>0.01</CtrlSum>
          <InitgPty>
            <Nm>TestCo</Nm>
          </InitgPty>
        </GrpHdr>
        <PmtInf>
          <PmtInfId>testmsg-1-pmt-1</PmtInfId>
          <PmtMtd>DD</PmtMtd>
          <BtchBookg>true</BtchBookg>
          <NbOfTxs>1</NbOfTxs>
          <CtrlSum>0.01</CtrlSum>
          <PmtTpInf>
            <SvcLvl>
              <Cd>SEPA</Cd>
            </SvcLvl>
            <LclInstrm>
              <Cd>CORE</Cd>
            </LclInstrm>
            <SeqTp>OOFF</SeqTp>
          </PmtTpInf>
          <ReqdColltnDt>2014-02-14+01:00</ReqdColltnDt>
          <Cdtr>
            <Nm>TestCo</Nm>
          </Cdtr>
          <CdtrAcct>
            <Id>
              <IBAN>DE54100000000000012345</IBAN>
            </Id>
          </CdtrAcct>
          <CdtrAgt>
            <FinInstnId>
              <BIC>MARKDEF1100</BIC>
            </FinInstnId>
          </CdtrAgt>
          <CdtrSchmeId>
            <Id>
              <PrvtId>
                <Othr>
                  <Id>DE46ZZZ00000012345</Id>
                  <SchmeNm>
                    <Prtry>SEPA</Prtry>
                  </SchmeNm>
                </Othr>
              </PrvtId>
            </Id>
          </CdtrSchmeId>
          <DrctDbtTxInf>
            <PmtId>
              <EndToEndId>testmsg-1-2</EndToEndId>
            </PmtId>
            <InstdAmt Ccy="EUR">0.01</InstdAmt>
            <DrctDbtTx>
              <MndtRltdInf>
                <MndtId>Test-1</MndtId>
                <DtOfSgntr>2014-02-14+01:00</DtOfSgntr>
              </MndtRltdInf>
            </DrctDbtTx>
            <DbtrAgt>
              <FinInstnId>
                <BIC>MARKDEF1200</BIC>
              </FinInstnId>
            </DbtrAgt>
            <Dbtr>
              <Nm>Other Test</Nm>
            </Dbtr>
            <DbtrAcct>
              <Id>
                <IBAN>DE90200000000000098765</IBAN>
              </Id>
            </DbtrAcct>
            <RmtInf>
              <Ustrd>Test</Ustrd>
            </RmtInf>
          </DrctDbtTxInf>
        </PmtInf>
      </CstmrDrctDbtInitn>
    </Document>
  </MsgPain008>
</conxml>

According to a bank-supplied format checking tool my file is mostly correct, except for the hash. Since PHP's implementation of SHA256 is probably not at fault I think I'm doing something wrong when canonicalizing the document.

The code in question is rather simple:

function documentHash($element)
{
    $text = $element->C14N(true, true);
    return strtoupper(hash('sha256', $text));
}

$element is the DOMElement containing the <Document> node. This function is called during the creation of the container file; thus the xmlns:xsi parameter is not applied to the node. However, manually adding it did not seem to improve matters.

The generated hash is wrong - it's 058098433DAC5D66ED34933CFFD98BF65CAD5C97CC45F9B0619B1FF96C3930E7; the expected value according to the format checker is 942AB2F57DBAF6302EDC526472098DF38C540EB75E1913DAB0DF416D168C3253. Now the question is what I'm doing wrong here - or rather how the I have to massage my XML in order to please the bank.

Here is what $text looks like: (Unfortunately, canonicalized XML does not make for pretty code blocks.)

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.003.02"><CstmrDrctDbtInitn><GrpHdr><MsgId>testmsg-1</MsgId><CreDtTm>2014-02-14T09:32:37+01:00</CreDtTm><NbOfTxs>1</NbOfTxs><CtrlSum>0.01</CtrlSum><InitgPty><Nm>TestCo</Nm></InitgPty></GrpHdr><PmtInf><PmtInfId>testmsg-1-pmt-1</PmtInfId><PmtMtd>DD</PmtMtd><BtchBookg>true</BtchBookg><NbOfTxs>1</NbOfTxs><CtrlSum>0.01</CtrlSum><PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl><LclInstrm><Cd>CORE</Cd></LclInstrm><SeqTp>OOFF</SeqTp></PmtTpInf><ReqdColltnDt>2014-02-14+01:00</ReqdColltnDt><Cdtr><Nm>TestCo</Nm></Cdtr><CdtrAcct><Id><IBAN>DE54100000000000012345</IBAN></Id></CdtrAcct><CdtrAgt><FinInstnId><BIC>MARKDEF1100</BIC></FinInstnId></CdtrAgt><CdtrSchmeId><Id><PrvtId><Othr><Id>DE46ZZZ00000012345</Id><SchmeNm><Prtry>SEPA</Prtry></SchmeNm></Othr></PrvtId></Id></CdtrSchmeId><DrctDbtTxInf><PmtId><EndToEndId>testmsg-1-2</EndToEndId></PmtId><InstdAmt Ccy="EUR">0.01</InstdAmt><DrctDbtTx><MndtRltdInf><MndtId>Test-1</MndtId><DtOfSgntr>2014-02-14+01:00</DtOfSgntr></MndtRltdInf></DrctDbtTx><DbtrAgt><FinInstnId><BIC>MARKDEF1200</BIC></FinInstnId></DbtrAgt><Dbtr><Nm>Other Test</Nm></Dbtr><DbtrAcct><Id><IBAN>DE90200000000000098765</IBAN></Id></DbtrAcct><RmtInf><Ustrd>Test</Ustrd></RmtInf></DrctDbtTxInf></PmtInf></CstmrDrctDbtInitn></Document>
Community
  • 1
  • 1
Tim Okrongli
  • 169
  • 2
  • 8
  • Could you solve this? I am working on this for the last 6 hours. It looks like C14N does not canonize as required. I found [this](http://www.w3.org/TR/2001/REC-xml-c14n-20010315) but I am not sure if C14N implements this or if there is any open source php library that implemts this. – AbcAeffchen Oct 21 '14 at 05:13
  • Unfortunately I don't have an answer. For my use case I managed to find a way to submit my data without having to go through the container format so I just abandoned work on containers altogether. One avenue you might try would be to find open source software in any language that calculates the proper hash value, modify it to dump the C14N'd XML and then compare that to what PHP generates. Perhaps that might give you a clue to what's going on here. Good luck. – Tim Okrongli Oct 21 '14 at 09:49
  • Thanks. I thought about calculating the correct canonization with an other program and compare the results, but I think this will be a lot of work. So I have to let it go until I have more time. If I find the answer, I will post it here ;) – AbcAeffchen Oct 21 '14 at 12:59

0 Answers0