3 votes

C# Calculer la valeur SHA256 pour le fichier de paiement SEPA (XML)

Dans la spécification de l'"accord DFÜ", il est décrit de calculer la valeur de hachage pour un fichier de paiement de conteneur SEPA par SHA256.

La valeur de hachage est créée à partir de l'ensemble du document contenu, y compris l'ouverture. et la balise "document" fermante.

Le document est canonisé selon la norme Canonical XML, version 1.0. ( http://www.w3.org/TR/2001/REC-xml-c14n-20010315 ).

Dans le cas de documents inclus, la canonisation doit également être exécutée selon le document principal.

SHA-256 est utilisé comme algorithme de hachage.

La valeur de hachage est saisie sous forme hexadécimale dans la balise, les caractères majuscules étant utilisés pour les chiffres hexadécimaux A à F. Lors de l'utilisation d'un conteneur XML dans le cadre de la procédure SRZ, il est obligatoire de spécifier la valeur de hachage (l'abréviation SRZ est l'abréviation du terme allemand "Servicerechenzentrum" qui signifie "centre de service de traitement des données").

J'ai essayé différentes manières de le faire mais je n'arrive pas à obtenir la valeur correcte.

    [Test]
    public void GetHashTest()
    {
        // load document
        XmlDocument sepaContainer = new XmlDocument();
        sepaContainer.PreserveWhitespace = true;
        sepaContainer.Load("PathToFile");

        // do canonical 
        XmlDsigC14NTransform transformer = new XmlDsigC14NTransform();
        transformer.LoadInput(document);

        string compare = string.Empty;
        foreach (byte b in transformer.GetDigestedOutput(new SHA256Managed()))
        {
            compare += b.ToString("X2");
        }

        Assert.That(compare, Is.EqualTo("1FA8EE4F1E9551C82E1C7A82A88140325453A52BD08FF9FA5D13CA40F04AB305"));
    }

Cela ne fonctionne pas non plus pour lire le fichier dans une chaîne de caractères et calculer :

    private string GetSHA256(string text)
    {
        UTF8Encoding UE = new UTF8Encoding();
        byte[] message = UE.GetBytes(text);

        SHA256Managed hashString = new SHA256Managed();
        string hex = string.Empty;

        byte[] hashValue = hashString.ComputeHash(message);
        foreach (byte x in hashValue)
        {
            hex += string.Format("{0:X2}", x);
        }

        return hex;
    }

Actuellement, je travaille avec le conteneur SEPA XML d'ici : http://entwickler-forum.de/showthread.php/64499-Auslesen-einer-XML-Datei

<?xml version="1.0" encoding="UTF-8"?>
<conxml xmlns="urn:conxml:xsd:container.nnn.002" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:conxml:xsd:container.nnn.002 container.nnn.002.xsd">
  <CreDtTm>2010-10-26T14:48:17Z</CreDtTm>
  <MsgPain008>
    <HashValue>38B862BD35B95D8CB20448153B5F6F73B3657EB1BC81CF11D3491D16EEA94009</HashValue>
    <HashAlgorithm>SHA256</HashAlgorithm>
    <Document xmlns="urn:swift:xsd:$pain.008.002.01">
      <pain.008.001.01>
        <GrpHdr>
          <MsgId>D004201010261648081</MsgId>
          <CreDtTm>2010-10-26T14:48:08Z</CreDtTm>
          <NbOfTxs>1</NbOfTxs>
          <CtrlSum>0.20</CtrlSum>
          <Grpg>MIXD</Grpg>
          <InitgPty>
            <Nm>Testauftraggeber SEPA-LS</Nm>
          </InitgPty>
        </GrpHdr>
        <PmtInf>
          <PmtInfId>D00420101024444444081</PmtInfId>
          <PmtMtd>DD</PmtMtd>
          <PmtTpInf>
            <SvcLvl>
              <Cd>SEPA</Cd>
            </SvcLvl>
            <LclInstrm>
              <Cd>CORE</Cd>
            </LclInstrm>
            <SeqTp>OOFF</SeqTp>
          </PmtTpInf>
          <ReqdColltnDt>2010-11-02</ReqdColltnDt>
          <Cdtr>
            <Nm>Testauftraggeber SEPA-LS</Nm>
          </Cdtr>
          <CdtrAcct>
            <Id>
              <IBAN>DE352505018444402014</IBAN>
            </Id>
          </CdtrAcct>
          <CdtrAgt>
            <FinInstnId>
              <BIC>SPKHDE2HXXX</BIC>
            </FinInstnId>
          </CdtrAgt>
          <ChrgBr>SLEV</ChrgBr>
          <DrctDbtTxInf>
            <PmtId>
              <EndToEndId>Lastschriftreferenz 002</EndToEndId>
            </PmtId>
            <InstdAmt Ccy="EUR">0.20</InstdAmt>
            <DrctDbtTx>
              <MndtRltdInf>
                <MndtId>Mandat002</MndtId>
                <DtOfSgntr>2010-10-26</DtOfSgntr>
                <AmdmntInd>false</AmdmntInd>
              </MndtRltdInf>
              <CdtrSchmeId>
                <Id>
                  <PrvtId>
                    <OthrId>
                      <Id>DE98ZZZ09999999999</Id>
                      <IdTp>SEPA</IdTp>
                    </OthrId>
                  </PrvtId>
                </Id>
              </CdtrSchmeId>
            </DrctDbtTx>
            <DbtrAgt>
              <FinInstnId>
                <BIC>SPKHDE2HXXX</BIC>
              </FinInstnId>
            </DbtrAgt>
            <Dbtr>
              <Nm>Test Zahlungspflichtiger</Nm>
            </Dbtr>
            <DbtrAcct>
              <Id>
                <IBAN>DE132505018005555552</IBAN>
              </Id>
            </DbtrAcct>
            <UltmtDbtr>
              <Nm>Test Miete</Nm>
            </UltmtDbtr>
            <RmtInf>
              <Ustrd>Test SEPA-LS Einzug durch 10002014 Zahlungspflichtiger 10002022</Ustrd>
            </RmtInf>
          </DrctDbtTxInf>
        </PmtInf>
      </pain.008.001.01>
    </Document>
  </MsgPain008>
</conxml>

J'ai extrait le noeud "Document" à la main et par xpath mais j'ai toujours obtenu une valeur différente de celle calculée pour le hachage de contrôle.

J'espère que l'un d'entre vous a une idée ?

EDIT : 26.08.2013 - modifié (corrigé) la valeur de hachage donnée du fichier xml

1voto

Markus Dreyer Points 41

Ok, je veux informer de la solution, peut-être que quelqu'un trouvera ce sujet :
Le nœud du document doit être sélectionné directement de cette manière à partir du conteneur : "XmlNodeList documentNodeList = sepaContainer.GetElementsByTagName("Document") ;"

alors le xml extérieur de la première entrée doit être canonisé et converti en hash.

aussi la première valeur affichée : 7DDB2138E8C91037DA7A6E9552478C59A2AACE26F8112EBC8012A8DE11592025 est erronée, la valeur correcte est 38B862BD35B95D8CB20448153B5F6F73B3657EB1BC81CF11D3491D16EEA94009.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X