C++ Passwort einlesen ohne Klartext anzuzeigen



  • Hallo zusammen ich habe jetzt eine Weile herumgesucht aber keine wirkliche Lösung gefunden. Was ich machen möchte steht größtenteils im Titel. Ich möchte den User über die Konsole ein Passwort eingeben lassen dieses soll jedoch selbstverständlich nicht als Klartext angezeigt werden wie es cin oder getline() tun würden. Ich verwende also eine Schleife und getch() um einen String zu füllen und gebe als kleines Extra nach jedem Tastendruck ein * aus. Jetzt kann der User seine Eingabe beenden indem er wie gewohnt Enter drückt. Rufe ich nun allerdings wieder meine Funktion auf und möchte neuen Input abspeichern so besteht dieser Druck auf die Enter Taste irgendwie noch und sobald man eine Taste drückt beendet sich die Eingabe als ob man Enter gedrückt hätte. Ich habe es schon mit cin.ignore() versucht jedoch kann ich dann gar keine Eingabe mehr tätigen.
    Hier mein Code ich hoffe ihr könnt mir helfen.

    void get_input(string &var)
    {
        char ch; //Variable für Rückgabewert von getch()
    
        do
        {
           ch = getch(); //abfangen des eingegebenen Zeichens
           cout << "*"; //Ausgabe des *
           var += ch; // Anhaengen des eingegebenen Zeichens an den String
        } while (!GetAsyncKeyState(VK_RETURN)); //Bedingung: Solange nicht Enter gedrückt wird
    
        var.pop_back(); //Löschen des 'Enter' als char am Ende des Strings
    }
    

    Ich hoffe ihr könnt mir helfen und ich habe mich akurat genug ausgedrückt sodass ihr mein Problem versteht.



  • Hallöchen,

    ich hab das hier irgendwo rumstehen, hab ich vor einiger Zeit mal gemacht.

    Inwiefern das protabel/gut/brauchbar ist, kann ich dir nur bedingt sagen. Es war eher als triviales Spaßprojekt gedacht. Aber vielleicht hilft es dir irgendwie 🙂

    #include<iostream>
    #include<string>
    #include <conio.h>
    
    bool verify_pass(const std::string& pass)
    {
        std::string input = "";
        char ch = '0';
        while(true)
        {
            ch = getch();
            if(ch == '\b')
            {
                if(input.size() > 0)
                {
                    input.erase(input.begin() + input.size() - 1);  // erase last char
                    std::cout << "\b \b";
                }
            }
            else if(ch != '\r' && ch != '\n')
            {
                input += ch;
                std::cout << '*';
            }
            else
                break;
        }
        return input == pass;
    }
    
    int main()
    {
        std::string insecurePass = "1234";
        std::cout << "Enter Password: ";
    
        if(verify_pass(insecurePass))
            std::cout << "\nCorrect!\n";
        else
            std::cout << "\nFalse!\n";
    
    }
    
    /*
    std::string get_pass()
    {
        std::string input;
        char ch = '0';
        while(true)
        {
            ch = getch();
            if(ch == '\b')
            {
                if(input.size() > 0)
                {
                    input.erase(input.begin() + input.size() - 1);  // erase last char
                    std::cout << "\b \b";
                }
            }
            else if(ch != '\r')
            {
                input += ch;
                std::cout << '*';
            }
            else
                break;
        }
        return input;
    }
    */
    

    P.S.: Ich denke es muss nicht noch gesagt werden aber: Für ernst gemeinte Sachen sollten Passwörter sicher nicht als Klartext im Quellcode gespeichert werden. Wie man am besten Passwörter speichert findet man sicher im Internet.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (alle ISO-Standards) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hey danke für die späte Antwort Funktioniert einwandfrei! Gibt es einen grund wieso du für die Löschung des letzten chars std::string::erase() benutzt statt std::string::pop_back()?
    Und wieso funktioniert mein Code nicht? Ich glaube ich habe noch etwas bei der Eingabeverarbeitung nicht recht verstanden.



  • Bei mir ist es nicht so spät, ich bin momentan nicht in der deutschen Zeitzone:P

    Gibt es einen grund wieso du für die Löschung des letzten chars std::string::erase() benutzt statt std::string::pop_back()?

    Wie gesagt, ist lang her... glaube nicht... habs einfach gemacht. Vielleicht kannte ich pop_back() nicht

    Um dein "Druck mit der enter taste" problem zu lösen könntest du z.B.: einfach das Zeichen einlesen, anstatt mit GetAsynch irgendwas zu arbeiten (das finde ich persönlich irgendwie keine so tolle Lösung, streams und das windows keystate zeugs zu vermischen). Also in etwa so wie ich es in meinem code mache (prüfen auf '\r' oder '\n'. Ich hab zZ kein Linux, aber ich glaube irgendwie in Windows ist enter \r\n und in Linux nur \n, deshalb hatte ich da versucht das für beide OS funktionsfähig zu machen).

    Also z.B. so:

    void get_input(std::string &var)
    {
        char ch = getch();
        while (ch != '\r' && ch != '\n')
        {
            std::cout << "*";
            var += ch;
            ch = getch();
        }
    }
    

    P.S.: Schau mal in der sufu. Ich könnte mir vorstellen, dass es da schon was gibt. Erfahrungsgemäß antwortet oft der Werner auf einlese Fragen. Vllt. wirst du noch mit professionellem Rat beglückt^^ Was exakt bei deinem code jetzt schiefläuft kann ich dir leider nicht erklären, da sind meine Kenntnisse mit der WinAPI und streams zu rostig..



  • Ja ich finde deine Lösung auch sehr schön gefällt mir viel besser. Hatte auch irgendwie den Gedanken, dass das Enter durch die Verwendung von GetAsyncKeyState() nicht abgefangen wird. Ich wusste nur nicht wie ein Enter im System dargestellt wird und das mit dem \b kannte ich auch noch überhaupt nicht ich danke dir vielmals und wünsche dir noch eine/n schöne/n Tag/Abend/Nacht.



  • Freut mich, dass die Version dir gefällt.

    Ich möchte dir aber zu Herzen legen das Ganze erst durch jemanden der wirklich Ahnung hat "verifizieren" zu lassen, bevor du es für ernsthafte Sachen verwendest...



  • Ist nichts wirklich ernstes also mir gibt dafür leider niemand Geld oder hat einen spannenden Auftrag für mich.
    Wollte nur ein Programm haben wo ich alle meine Passwörter speichern kann sodass ich auch mal ein Passwort wie "sdnfiosnho374z" haben kann und es trotzdem immer abrufbar habe. Nur falls ich es halt mal an Freunde weitergeben möchte sollte es auch gut zu nutzen sein und ein bisschen was hermachen.




Log in to reply