BMF-RKSV-Technik / at-registrierkassen-mustercode

112 stars 39 forks source link

turnover encyption failed trotz übereinstimmung mit demo kasse #726

Closed zgast closed 6 months ago

zgast commented 6 months ago

Meine BASE64 hashes stimmen genau mit der von der Demokasse überein, ich kann die Demokasse leider nicht komplett komplieren und nutzen, da es diverse errors gibt (?) aber ich hab den encryption/decryption (CTR) algo zum laufen gebracht und damit auch diesen gegen meinen eigenen gecheckt und habe auch die Testdaten wo die decryption im Prüftool nicht failed aus dem 1.0.0 release gegengetestet (Die überhaupt auch nicht komplett passen, sowohl beim 1.0.0 als auch beim neuesten Prüftool, ist das absicht?). Ich sehe keinen Fehler, da mein Algorithmus anscheinend ja funktioniert, jetzt ist die Frage ob ich etwas übersehe, das Prüftool falsch ist oder die Demobox falsch ist.

Mit diesen Daten:

    KassenID:               "0",
    Belegnummer:            "start-beleg",
    BelegtDatumUhrzeit:     "2024-01-21T14:23:34",
    BetragSatzNormal:       0.00,
    BetragSatzErmaessigt1:  0.00,
    BetragSatzErmaessigt2:  0.00,
    BetragSatzNull:         0.00,
    BetragSatzBesonders:    0.00,
    UmsatzBevor:            0.00,
    ZertifikatSeriennummer: certNr,
    JWSVorigerBeleg:        "",

Key: 4wG+kZghA5c/259BW9o+40m1Q9Co27l29YHQUSrPFU4= Hash Algo: SHA256

Bekomme ich folgenden hash: aepYIfPX0+A=

Welcher so ebenfalls bei der Implimentierung der DemoCashBox rauskommt und sich dadurch auch wunderbar decrypten lässt.

Mein algo in golang:

func EncryptCTR(hashValue []byte, turnoverCounter int64, symmetricKey []byte, turnOverCounterLengthInBytes int) (string, error) {
    if len(hashValue) < 16 {
        return "", errors.New("hashValue must be at least 16 bytes long")
    }
    IV := hashValue[:16]

    data := make([]byte, 16)
    binary.BigEndian.PutUint64(data, uint64(turnoverCounter))

    turnOverCounterByteRep := data[:turnOverCounterLengthInBytes]

    block, err := aes.NewCipher(symmetricKey)
    if err != nil {
        return "", err
    }

    stream := cipher.NewCTR(block, IV)
    encryptedTurnOverValue := make([]byte, len(turnOverCounterByteRep))
    stream.XORKeyStream(encryptedTurnOverValue, turnOverCounterByteRep)

    encoded := base64.StdEncoding.EncodeToString(encryptedTurnOverValue)
    return encoded, nil

}
    IVUTF8StringRepresentation := data.KassenID + data.Belegnummer
    hasher := sha256.New()
    hasher.Write([]byte(IVUTF8StringRepresentation))
    hashValue := hasher.Sum(nil)

    concatenatedHashValue := hashValue[:16]

    fmt.Println("IV:" + base64.StdEncoding.EncodeToString(concatenatedHashValue))

    turnoverCounter := int64((data.UmsatzBevor + data.BetragSatzNormal + data.BetragSatzBesonders + data.BetragSatzErmaessigt1 + data.BetragSatzErmaessigt2 + data.BetragSatzNull) * 100)

    fmt.Println(turnoverCounter)
    symmetricKey, err := base64.StdEncoding.DecodeString(aesKeyBase64)
    if err != nil {
        return "", err
    }

    turnOverCounterLengthInBytes := 8
    StandUmsatzZaehlerAES256ICM, err := EncryptCTR(concatenatedHashValue, turnoverCounter, symmetricKey, turnOverCounterLengthInBytes)

Hier ebenfalls die DEP und die CMC zum testen:

export_cmc.json export_dep.json

zgast commented 6 months ago

das prüftool war das problem - man MUSS java 8 nutzen