Joomla 4 Passwort für Datenbank verschlüsseln

  • Hallo,


    ich nutze aktuell eine Erweiterung für Fronend-Formulare.


    Eines meiner Formular soll es dem angemeldeten Benutzer ermöglichen seine Benutzerdaten und auch sein Passwort zu ändern.


    Frage: wenn ich das neue Passwort aus dem Formular in einem PHP Skript erhalte, wie kann ich dieses dann für die Datenbank richtig verschlüsseln?


    Ich suche seit gestern und habe bislang nur die folgende Information gefunden.


    Code
    jimport('joomla.user.helper');
    $pass = JUserHelper::hashPassword($password);

    Leider scheint da noch etwas zu fehlen. Die Passwörter für Joomla 4 sehen in der Datenbank eher wie folgt aus:


    "$2y$1... usw.".


    Ich erhalte aber:


    "9475... usw."

  • Bau ich mir ein Test-Script unter Joomla 4, z.B am Anfang meiner Template index.php:

    PHP
    <?php
    defined('_JEXEC') or die;
    
    use Joomla\CMS\User\UserHelper;
    
    $password = 'isKokolores';
    
    $hashed = UserHelper::hashPassword($password);
    
    echo ' DEBUG <pre>' . print_r($hashed, true) . '</pre>';exit;

    bekomme ich ein Password, das mit $2y beginnt. Warum? Weil Joomla dann auf den BCRYPT-Algorithmus zurückfällt:

    Siehe "$algorithm = self::HASH_BCRYPT" https://github.com/joomla/joom…/User/UserHelper.php#L432


    Und der verwendet eben als Kennung diesen einleitenden Schnipsel beim generierten Password:

    Code
    $2y.....

    Es macht auch keinen Unterschied, ob ich veraltetes, "unmodernes"

    Code
    $password = 'isKokolores';
    
    $hashed = JUserHelper::hashPassword($password);
    
    echo ' DEBUG <pre>' . print_r($hashed, true) . '</pre>';exit;

    verwende.


    Kurz: Dein Problem liegt woanders.

  • Joomla v4.1.5 in Kombination mit Convert Forms v3.2.5 Pro.


    Für angemeldete Benutzer habe ich ein eigenes Formular für die Änderung bestimmter Benutzerdaten erstellt. In diesem Formular möchte ich dem Nutzer die Möglichkeit geben, ebenfalls sein Passwort zu ändern.


    Wenn ich also $password als raw string in meinem Skript erhalte, wie kann ich dieses dann für die Datenbank aufbereiten?


    Danke für den Hinweis bezüglich BCRYPT-Algorithmus.

    Das werde ich später ausprobieren und ist ggf. schon die Lösung.


    Ist der Benutzer nicht angemeldet, würde ich die Joomla 4 eigenen Formulare für "Passwort vergessen" und "Benutzernamen vergessen" im Frontend nutzen!

  • Ein angemeldeter Benutzer kann im Frontend sein Profil bearbeiten, inklusive Passwort ändern

    Danke für den Hinweis. Ist mir bewusst. Ich möchte aber eine eigene Formular-Extension nutzen, die ich für eine Vielzahl an Formularen verwenden werde. Ein Vorteil ist die Einbindung der Formulare per Modul in mein aktuelles Template (Page Builder) und die Flexibilität in Bezug auf Custom PHP Code.

  • Aber dann kannst du doch trotzdem Joomla-4-Klassen für die Speicherung etc. verwenden, wie die save() für Joomla-User. Das kann einem sehr viel Arbeit abnehmen.


    joomla-cms/UserModel.php at 4.1.5 · joomla/joomla-cms
    Home of the Joomla! Content Management System. Contribute to joomla/joomla-cms development by creating an account on GitHub.
    github.com

    und/oder

    joomla-cms/ProfileModel.php at 4.1.5 · joomla/joomla-cms
    Home of the Joomla! Content Management System. Contribute to joomla/joomla-cms development by creating an account on GitHub.
    github.com


    Die UserHelper-Klasse ist ja nur ein Helferlein, aber erspart einem nun nicht wirklich so viel Programmierarbeit. EDIT: Aber hat natürlich auch die eine oder andere "schnelle Methode" dabei, die man gelegentlich mal brauchen könnte.

  • Re:Later


    Danke für den Hinweis.


    Ich muss noch einmal nachfragen. Ich verwende die aktuellste Joomla Version 4.1.5.


    Wenn die Passwörter in der Datenbanktabelle "users" in dem Format "$2y... usw." gespeichert sind, wird dann der BCRYPT-Algorithmus verwendet?


    So habe ich deinen Hinweis verstanden.


    Wie wende ich diesen richtig an?


    Nachfolgender Code schreibt anscheinend ein anderes Passwort-Format in die Datenbank.


    Code
    jimport('joomla.user.helper');
    $hashed = UserHelper::hashPassword($password);

    Was ist denn die aktuelle Methode zur Verschlüsselung von Passwörtern?


    Ich denke => Joomla 4 only supports hashing with the native PHP password_hash function (via JUserHelper::hashPassword).


    Damit erhalte ich aber "a37fd...usw."


    Macht es in der neusten Joomla Version einen Unterschied ob ich die Klasse via "JUserHelper" bzw. "UserHelper" anspreche?

  • Damit erhalte ich aber "a37fd...usw."

    Habe ich oben schon alles zu gesagt. Und wie man den Code richtig anwendet ebenfalls.


    Auch zu allen deinen weiteren Fragen habe ich eigentlich schon alles gesagt. Inklusive, dass dein Code halt veraltet ist, aber trotzdem (noch) funktioniert. Man verwendet entweder am Beginn der Datei eine use-Zeile und UserHelper oder veraltetes JUserHelper. Beide verwenden aber die selbe Klasse, liefern das sel

    be Ergebnis. Zweite Variante wird mit Sicherheit unter Joomla 5 nicht mehr laufen. Also lieber gleich richtig.


    Das hier ist jedenfalls Joomla 2.5 und verwendet heute niemand mehr ;) :

    Code
    jimport('joomla.user.helper');


    Nachdem wir hier von Hashes reden, die erzeugt werden, ist natürlich das Ergebnis bei jedem Durchlauf des PHP-Codes ein anderes. Der Passwort String ändert sich.


    Was ist denn die aktuelle Methode zur Verschlüsselung von Passwörtern?

    So etwas gibt es nicht. Außerdem ist es genaugenommen keine Verschlüsselung.


    Wenn du Joomla seine Arbeit machen lässt, anstatt selber das Rad neu zu erfinden, testet Joomla, welche Hash-Methoden auf dem jeweiligen Server überhaupt verfügbar sind und nimmt dann die "beste" bevor es hashPassword() aufruft. In den meisten Standard-Serverfällen ist das derzeit (noch) BCRYPT.


    In deinem Fall wird halt BCRYPT verwendet, da du hashPassword() ohne Vorgabe aufrufst. Ich kann dir aber nicht empfehlen, da jetzt irgendeine andere Hash-Methode zu übergeben, weil wie gesagt server-und PHP-abhängig. https://github.com/joomla/joom…/UserHelper.php#L126-L135

    Wenn die Passwörter in der Datenbanktabelle "users" in dem Format "$2y... usw." gespeichert sind, wird dann der BCRYPT-Algorithmus verwendet?

    Wenn mein/dein Beispielcode mit BCRYPT arbeitet, hat der erzeugte Hash vorne ein $2y dran. Jeder Hash-Algorithmus hat seine Kennung, was du dir in der https://github.com/joomla/joom…s/src/User/UserHelper.php einfach zusammensuchen kannst.


    Unter Umständen kann es aber sein, dass BCRYPT auf BCRYPT_BC zurückfällt. Das hängt u.a. von der PHP-Version ab. Kann schon sein, dass die Passwörter dann mit 9 anfangen. Weiß ich nicht!!!!!!!!!!!!!!!!!!!!!!!!!!! Bei meinen Tests nicht. Sehe aber in der Datenbank zufällig auch ein Uraltkennwort, das mit 9 anfängt.


    Aber ist doch auch komplett wurst so lange das verifyPassword() https://github.com/joomla/joom…/User/UserHelper.php#L465 richtig verifiziert. Da findest übrigens weitere Hinweise zu deinen Fragen.


    Hier bin ich nicht sicher: Soweit ich mich erinnere, werden schwach gehashte Kennworte von Joomla bei der Nutzung neu und stärker gehasht. Zumindest bei md5-Passworten, die man ja öfters bei Notfall-Zugängen verwenden kann, ist das sicher der Fall.


    Kurz: Einfach mal rumprobieren und Codes durchwühlen, wenn man sie schon so schön verlinkt bekommt ;) Hab ich ja seinerzeit auch machen müssen, allerdings im Zusammenhang mit einem Joomla-Bug oder Hoster-Bug (keine Ahnung mehr).

  • Danke.


    Also versucht Joomla 4 die beste Methode auf dem Server zu finden, um das Passwort zu "verschlüsseln". Aber warum verschlüsselt Joomla 4 bei der Registrierung eines neuen Nutzers einmal mit der BCRYPT-Methode [$2y...] (zudem veraltet) und in meinem eigenen Skript mit etwas anderem?


    Für die Registrierung verwende ich ein eigenes Formular mit nachfolgendem Code (Convert Forms).


    Ich habe nun meine PHP Version von 7.4 auf 8.0 für Joomla 4.1.5 angehoben und werde diese beibehalten, solange keine Erweiterung etwas dagegen hat.


    JUserHelper und UserHelper => funktioniert also beides, wobei UserHelper die aktuellere Bezeichnung ist. Danke x2.


    Ursprünglich wollte ich einfach die Datei einbinden und nicht mit einem Auto-Loader arbeiten:

    Code
    include_once JPATH_BASE . '/libraries/src/User/UserHelper.php';


    Leider findet das Skript dann die Klasse nicht, obwohl andere Dateien wie die configuration.php korrekt eingebunden werden.


    Also nutze ich für UserHelper Namespaces am Anfang der Datei:

    Code
    defined('_JEXEC') or die;
    use Joomla\CMS\User\UserHelper;

    Dein Hinweis auf die save() Methode ist sehr nett, aber ich kenne mich so gut wie garnicht mit der Joomla API aus und habe auch keinen Ansprechpartner diesbezüglich (Hobby Programmierer). Ich versuche die Informationen im Netz zu finden, aber für Joomla 4 gibt es nicht wirklich brauchbare Tutorials. Zumindest finde ich keine und suche schon lange.

  • Also...mit nachfolgendem Code erhalte ich das gewünschte BCrypt Passwort


    Code
    $password = UserHelper::hashPassword($password, PASSWORD_BCRYPT);

    Und wie in der nachfolgenden Klasse zu sehen, wird BCrypt auch als Parameter übergeben:


    joomla-cms/UserHelper.php at 3.8.12 · joomla/joomla-cms
    Home of the Joomla! Content Management System. Contribute to joomla/joomla-cms development by creating an account on GitHub.
    github.com


    Code
        public static function hashPassword($password)
        {
            // \JCrypt::hasStrongPasswordSupport() includes a fallback for us in the worst case
            \JCrypt::hasStrongPasswordSupport();
    
            return password_hash($password, PASSWORD_BCRYPT);
        }


    Jetzt mache ich mir nur Sorgen, ob das für die Zukunft so richtig ist. Re:Later hat ja darauf hingewiesen, daß ich BCrypt eben nicht als Parameter übergeben sollte und Joomla eigenständig die beste Methode zur Verschlüsselung wählt.