2016-06-19 20 views
0

Ich versuche Hash-Passwörter in db zu speichern. Hier ist mein Code:Bcrypt Passwort validieren

string passwords = textBox2.Text; 
string salt = BCrypt.Net.BCrypt.GenerateSalt(12); 
string hashPwd = BCrypt.Net.BCrypt.HashPassword(passwords, salt); 
     try 
     { 
      SQLiteCommand command = new SQLiteCommand(); 
      connection.Open(); 
      command.Connection = connection; 
      command.CommandText = ((@"INSERT INTO acc (UserName, Pass) VALUES ('" + textBox1.Text + "','" + hashPwd+ "');")); 
      command.ExecuteNonQuery(); 
      connection.Close(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error:" + ex.ToString()); 
      return; 
     } 

Login/Bestätigungscode:

  try 
      { 

      SQLiteDataAdapter sqlad = new SQLiteDataAdapter("SELECT COUNT(*) From acc WHERE Username = '" + textBox1.Text + "' AND Pass = '" + textBox2.Text + "' ", connection); 
      DataTable dt = new DataTable(); 
      sqlad.Fill(dt);` 
      string userid = dt.Rows[0]["UserName"].ToString(); 
      string password = dt.Rows[0]["Pass"].ToString(); 
      bool flag = BCrypt.Net.BCrypt.Verify(textBox2.Text, password); 

      if (userid == textBox1.Text && flag == true) 
      { 
       Form2 frm = new Form2(); 
       frm.Show(); 
      } 
      else 
      { 
       MessageBox.Show("Invalid UserId or password"); 
      } 
      } 
      catch (Exception ex) 
      { 
      MessageBox.Show(ex.ToString()); 
      return; 
      } 

ich Passwort nicht überprüfen kann, ich Fehler bekommen, könnten Sie mir bitte helfen? Noch eine Frage, sollte ich auch Salz in der Datenbank speichern?

+2

Warum in Ihrer SELECT-Anweisung haben Sie 'UND Pass = ' "+ TextBox2.Text +"''? Das Passwort in Ihrer Datenbank ist gehashed und vermutlich enthält 'textBox2.Text' reinen Text, so dass dieser nichts finden würde.Sie geben auch die Anzahl zurück und nicht die Spalten 'UserName' und' Pass', so dass diese nicht in der Ergebnismenge enthalten sind. Schließlich möchte ich vielleicht SQL Injection lesen. – steve16351

+0

Wie kann ich das eingegebene Passwort des Benutzers mit einem Hash in der Datenbank vergleichen? –

+0

@LuisVito einen Blick auf [diesen Artikel] (https://crackstation.net/hashing-security.htm) und besonders auf [diesen Abschnitt] (https://crackstation.net/hashing-security.htm#properhashing) . Die relevanten Schritte sind dort aufgeführt. Und bitte lesen Sie den ganzen Artikel. es ist ein nettes :-) – khlr

Antwort

2

Es gibt ein paar Probleme mit Ihrem Code:

1. SQL Injection

Sowohl Ihr Einsatz und Bestätigungs-Code-Blöcke sind anfällig für SQL-Injection, da sie Text erlauben nehmen Sie direkt vom Benutzer Eingabe in die SQL-Zeichenfolge, die ausgeführt wird, eine Sicherheitsanfälligkeit, mit der die Anmeldeprüfung entweder unterlaufen oder die Datenbank zerstört werden kann. Tu es nicht!

2. Ihre Auswahl des Hash-Passwortes aus der Datenbank wählt nicht das Hash-Passwort .. oder etwas von Interesse.

Überlegen Sie, was Sie hier haben:

SQLiteDataAdapter sqlad = new SQLiteDataAdapter(@" 
    SELECT 
     COUNT(*) 
    From 
     acc 
    WHERE 
     Username = '" + textBox1.Text + "' 
     AND 
     Pass = '" + textBox2.Text + "' ", connection); 

So lassen Sie uns sagen, dass ich meinen Benutzernamen wie „Steve“ gab und das Passwort als „Hallo“, die „ab123cdef“ gehasht wurde, und eingefügt in Ihre acc Tabelle als:

UserName Pass 
Steve  ab123cdef 

und wenn ich komme, das mit dem ursprünglichen richtigen Benutzer und Kennwort zu überprüfen, Ihre Select-Anweisung sagt: „Gib mir die Anzahl der Zeilen mit Benutzername‚Steve‘und‚Hallo‘passieren“, die ordnungsgemäß Null zurückgeben.

Der Code sollte hier eine Ausnahme werfen:

string userid = dt.Rows[0]["UserName"].ToString(); 

Da die Ergebnismenge nicht den Benutzernamen als Ausgang enthält.

Hier ein kleines Beispiel, das anhand der ausgewählten Bibliotheken zeigt, wie Sie ein Kennwort erfolgreich einfügen und überprüfen können.

In Bezug auf was mit dem Salz zu tun, die Funktion HashPassword hat das Salz auf den Passwort-Hash vorangestellt, wenn Sie also die Ausgabe von diesem speichern, speichern Sie das Salz. Die Überprüfungsfunktion, die Sie bei der Verifizierung verwenden, wird dies für Sie übernehmen und überprüfen.

static void CreateUser(string username, string password) 
{ 
    if (UserExists(username)) 
     throw new InvalidOperationException("User already exists"); 

    string salt = BCrypt.Net.BCrypt.GenerateSalt(12); 
    // if you look at the hashed password, notice that it's prepended with the salt generated above 
    string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password, salt); 

    using (SQLiteConnection connection = new SQLiteConnection(connectionString)) 
    { 
     connection.Open(); 
     SQLiteCommand insertCommand = new SQLiteCommand(connection); 
     insertCommand.CommandText = @"INSERT INTO acc (UserName, Pass) VALUES (@username, @hashedPass);"; 
     // use parameterised queries to mitigate sql injection 
     insertCommand.Parameters.Add(new SQLiteParameter("@username", username)); 
     insertCommand.Parameters.Add(new SQLiteParameter("@hashedPass", hashedPassword)); 
     insertCommand.ExecuteNonQuery(); 
    } 
} 

Um einen bestimmten Benutzernamen/Passwort überprüfen wir alle wieder aus der Datenbank müssen die Ausgabe der Hash-Funktion ist zu überprüfen, gegen das, was uns gegeben wurde.

static bool Verify(string username, string password) 
{ 
    using (SQLiteConnection connection = new SQLiteConnection(connectionString)) 
    { 
     connection.Open(); 

     SQLiteCommand checkUserCommand = new SQLiteCommand(connection) 
     { 
      CommandText = @"SELECT Pass FROM acc WHERE UserName = @username;" 
     }; 

     checkUserCommand.Parameters.Add(new SQLiteParameter("@username", username)); 
     var hashedPassword = (string)checkUserCommand.ExecuteScalar();     
     return BCrypt.Net.BCrypt.Verify(password, hashedPassword);     
    } 
} 

Verwendung wäre so etwas wie ..

if (!UserExists(username)) 
{ 
    CreateUser(username, password); 
    Console.WriteLine("User {0} created", username); 
} 
else 
{ 
    bool loginOk = Verify(username, password); 
    Console.WriteLine("Login ok?: {0}", loginOk); 
} 
+0

Vielen Dank. Ich werde über Injektionen lesen. –