与this question类似,我试图计算SEPA容器文件的文档哈希值。这是我的代码当前生成的容器:
<?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>
根据银行提供的格式检查工具,我的文件大多是正确的,除了哈希。由于PHP对SHA256的实现可能没有错,我认为在规范化文档时我做错了。
有问题的代码很简单:
function documentHash($element)
{
$text = $element->C14N(true, true);
return strtoupper(hash('sha256', $text));
}
$element
是包含<Document>
节点的DOMElement。在创建容器文件期间调用此函数;因此xmlns:xsi
参数不会应用于节点。但是,手动添加它似乎并没有改善问题。
生成的哈希是错误的 - 它是058098433DAC5D66ED34933CFFD98BF65CAD5C97CC45F9B0619B1FF96C3930E7;根据格式检查器的期望值是942AB2F57DBAF6302EDC526472098DF38C540EB75E1913DAB0DF416D168C3253。现在问题是我在这里做错了什么 - 或者说我如何按摩我的XML以取悦银行。
以下是$text
的样子:(不幸的是,规范化的XML并不适用于漂亮的代码块。)
<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>