hbci4j / hbci4java

Java-based FinTS protocol implementation that supports all features (chipTAN, pushTAN, HHD, SEPA, PSD2,...)
GNU Lesser General Public License v2.1
147 stars 49 forks source link

Fehler nach Umstellung auf PSD2 #28

Closed blacktoby closed 5 years ago

blacktoby commented 5 years ago

Liebe Entwickler, ich habe meinen Bankimport nach der PSD2 Änderung auf PhotoTan umgestellt. Leider funktioniert das erzeugen, des HBCIHandler Objektes nicht mehr.

Der komplette Log: error.log

Meine Callback-Klasse:

    public void callback(HBCIPassport passport, int reason, String msg, int datatype, StringBuffer retData)
    {
        // Diese Funktion ist wichtig. Ueber die fragt HBCI4Java die benoetigten Daten von uns ab.
        switch (reason)
        {
            // Mit dem Passwort verschluesselt HBCI4Java die Passport-Datei.
            // Wir nehmen hier der Einfachheit halber direkt die PIN. In der Praxis
            // sollte hier aber ein staerkeres Passwort genutzt werden.
            // Die Ergebnis-Daten muessen in dem StringBuffer "retData" platziert werden.
            case NEED_PASSPHRASE_LOAD:
            case NEED_PASSPHRASE_SAVE:
                retData.replace(0,retData.length(),pin);
                break;

            // PIN wird benoetigt
            case NEED_PT_PIN:
                log.debug("NEED_PT_PIN");
                MatrixCode matrixCode = MatrixCode.tryParse(retData.toString());
                log.debug(retData.toString());
                if(matrixCode != null) {
                    log.debug("Was phototan request in PIN!");
                }
                retData.replace(0,retData.length(),pin);
                break;

            // BLZ wird benoetigt
            case NEED_BLZ:
                retData.replace(0,retData.length(),blz);
                break;

            // Die Benutzerkennung
            case NEED_USERID:
                log.debug("NEED_USERID");
                retData.replace(0,retData.length(),user);
                break;

            // Die Kundenkennung. Meist identisch mit der Benutzerkennung.
            // Bei manchen Banken kann man die auch leer lassen
            case NEED_CUSTOMERID:
                log.debug("NEED_CUSTOMERID");
                retData.replace(0,retData.length(),user);
                break;

            // Manche Fehlermeldungen werden hier ausgegeben
            case HAVE_ERROR:
                log.error(msg);
                break;

            case NEED_HOST:
                log.debug("NEED_HOST");
                break;

            case NEED_PT_PHOTOTAN:
                log.debug("NEED_PT_PHOTOTAN");
                matrixCode = MatrixCode.tryParse(retData.toString());
                try {
                    log.debug("photo type: {}", matrixCode.getMimetype());
                    FileUtils.writeByteArrayToFile(new File("phototan.jpg"), matrixCode.getImage());
                } catch (IOException e) {
                    log.debug("Error writing phototan: {}", e.getMessage());
                }
                retData.replace(0,retData.length(),"");
                break;

            case NEED_PT_SECMECH:
                log.debug("NEED_PT_SECMECH");
                // 901:mobileTAN-Verfahren|902:photoTAN-Verfahren
                retData.replace(0, retData.length(), "902");
                break;

            default:
                log.debug("NEED SOMETHING ELSE!!");
                log.debug("{}", reason);
                // Wir brauchen nicht alle der Callbacks
                break;

        }
    }

Funktionen zum Bauen des Handlers:

private HBCIHandler buildHandler() {
        setProperties();
        HBCIPassport passport = buildPassport();
        return new HBCIHandler(VERSION.getId(), passport);
    }

    private void setProperties() {
        Properties properties = new Properties();
        HBCIUtils.init(properties, new HBCICallback(user, pin, blz));
        final File passportFile = new File("passport.dat");

        HBCIUtils.setParam("client.passport.default","PinTan"); // Legt als Verfahren PIN/TAN fest.
        HBCIUtils.setParam("client.passport.PinTan.filename",passportFile.getAbsolutePath());
        HBCIUtils.setParam("client.passport.PinTan.init","1");
    }

    private HBCIPassport buildPassport() {
        HBCIPassport passport = AbstractHBCIPassport.getInstance();
        passport.setCountry("DE");

        BankInfo info = HBCIUtils.getBankInfo(blz);
        passport.setHost(info.getPinTanAddress());
        passport.setPort(443);
        passport.setFilterType("Base64");
        return passport;
    }

Die Frage ist: Was mache ich falsch? Ich bin bei der comdirect und habe dort schon über Probleme gelesen und daher auf Version 3.1.13 des hbci4j-core geupdated.

Ich liefere gerne noch mehr Informationen!

Grüße

willuhn commented 5 years ago

Dein Fehler ist vermutlich, dass du als TAN-Verfahren in "NEED_PT_SECMECH" pauschal "902" zurücklieferst, du also davon ausgehst, dass dieses TAN-Verfahren bei der Bank existiert.

Das ist falsch. Stelle sicher, dass du den Callback HBCICallback.NEED_PT_SECMECH mit einem TAN-Verfahren beantwortest, welches auch in de uebergebenen Liste enthalten ist. Du musst schon auch die Werte pruefen, die in dem Callback zur Auswahl angeboten werden und nicht pauschal ein gespeichertes verwenden.

Identisch zu Issue #27

blacktoby commented 5 years ago

Danke für die schnelle Antwort. Ich habe natürlich die übergebene Liste gesehen und die Werte geprüft!! Das war die Antwort:

901:mobileTAN-Verfahren|902:photoTAN-Verfahren

Daher ist die Antwort die ich zurück gebe richtig.

willuhn commented 5 years ago

Dann weiss ich es leider auch nicht. Deinem Log kann man die Ursache nicht entnehmen, da du die Logausgaben von HBCI4Java selbst scheinbar nicht loggst. Versuche den Account zum Vergleich mal in Hibiscus anzulegen. Im Forum unter https://homebanking-hilfe.de/forum/index.php?f=33 findest du sicher auch passende Threads zur Comdirect.

blacktoby commented 5 years ago

Ich logge HBCI4Java schon, durch den log - Callback des HBCICallback. Alle Ausgaben mit dem Pfad "de.bankdataimport.HBCICallback" können auch aus dem HBCI Kernel kommen. Gibt es noch einen anderen Weg auf dem die Library loggt?

willuhn commented 5 years ago

HBCI4Java loggt nur ueber den Callback. In deinen Logs habe ich diese Ausgaben aber nicht gesehen. Wie dem auch sei. Teste mal Hibiscus. Dort kannst du ja verifizieren, ob HBCI4Java grundsaetzlich funktioniert. Hibiscus verwendet das ja intern ebenfalls.

fmux commented 4 years ago

Hallo @blacktoby,

ich weiß nicht, ob das Problem bei dir noch aktuell ist, aber da ich auch gerade an diesem Punkt war, hier schnell meine Lösung: Die in deinem Error-Log enthaltene Message "message has no signature" bzw. "Nachricht ist nicht verschlüsselt" zeigt an, dass die TAN fehlt.

Das Problem liegt in den Zeilen:

        case NEED_PT_PHOTOTAN:
            log.debug("NEED_PT_PHOTOTAN");
            matrixCode = MatrixCode.tryParse(retData.toString());
            try {
                log.debug("photo type: {}", matrixCode.getMimetype());
                FileUtils.writeByteArrayToFile(new File("phototan.jpg"), matrixCode.getImage());
            } catch (IOException e) {
                log.debug("Error writing phototan: {}", e.getMessage());
            }
            retData.replace(0,retData.length(),"");
            break;

Du lieferst in der letzten Zeile vor dem break in retData einen leeren String zurück.Stattdessen solltest du das in phototan.jpg gespeicherte Bild anzeigen, und den User die zugehörige TAN (als String) eingeben lassen. Diese gehört dann in retData.

blacktoby commented 4 years ago

@fmux Das war nicht das Problem. Ich habe falsche Daten an die Bank übergeben, also ein einfacher ''Leichtsinnsfehler''. Zwar stimmt was du schreibst, doch war ich noch dabei das Bild überhaupt zu empfangen.

fmux commented 4 years ago

Na dann schön, dass es doch noch geklappt hat :)

Es zeigt allerdings, dass die Fehlermeldung mit der fehlenden Signatur bzw. Verschlüsselung noch etwas nichtssagender ist als gedacht...