Autor Beitrag
Csharp-programmierer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: So 13.11.16 18:15 
Hallo Forum,
wie ihr sicherlich wisst, schreibe ich ein Admin Programm für das Netzwerk. Ich als Hauptadministrator kann dann jeden Unteradministrator Rechte vergeben. Das Prinzip bisher funktioniert tadellos, aber es gibt im Moment noch ein kleines Sicherheitsproblem: wenn sich ein Administrator anmeldet, wird das Passwort im Moment noch als Plain Text zu dem Server geschickt, der dann die Gültigkeit überprüft.

Wie kann man diesen Prozess noch sicherer machen? Bzw. kann die C# Anwendung das Passwort genau so hashen, wie die PHP Datei? Also wie kann man die Kommunikation am sichersten machen?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: So 13.11.16 23:35 
Du hast ja sicher auf dem Server nur eine Hash (Bspw. SHA-1 oder SHA-384) gespeichert.

Nun kannst du vom Programm zum Server erst mal eine "Anmeldeanfrage" schicken. Dieser sollte dann mit einem Zeitstempel und einer Zufallszahl (nonce) antworten. Auf dem Client berechnest du jetzt eine Hashwert:
ausblenden C#-Quelltext
1:
var answer = hash(timestamp + nonce + hash(passwort))					

Das Ergebnis schickst du zurück zum Server. Dieser hat sich natürlich die Zufallszahl aus Schritt 1 gemerkt und berechnet nun das gleiche, nur dass in der Datenbank ja schon "hash(passwort)" drin stehen sollte. Falls das Ergebnis identisch ist, kann der Server davon ausgehen, dass der Client das korrekte Passwort vorliegen hat. Das Passwort an sich geht dabei nie über das Netzwerk.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Mo 14.11.16 16:07 
also beispielsweise so: 14112015216253716235diesisteinpasswort123wer89w7e78w6er?

Und dann wird das Datum und die Zufallszahl in der PHP Datei einfach vorne bzw. hinten angehängt und dann über Passwort verify geckeckt? Und wenn sich dann 2 Administratoren gleichzeitig anmelden, gibt es dann keine Probleme? Wenn man in C# eine Zufallszahl generiert, dann wird immer die selbe Reihenfolge ausgegeben, kann das hier zum Verhängnis werden?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mo 14.11.16 18:20 
Die Idee dahinter ist, dass der Client nie das Passwort, nicht mal den Hash des Passwortes zum Server schickt.
Wie Du das nun machst, ist an sich unwichtig, das kann eine Zufallszahl sein oder eine Guid.
Hauptsache, der Hash des Passwortes allein wird nicht verschickt.

Ich persönlich würde es so machen:

Wenn das Passwort auf der Datenbank gespeichert wird, dann wird ein Hash des Passwortes erzeugt, gesalzen mit der Usernamen.
So sehen auch Passwort-Hashes bei gleichem Passwort immer anders aus.
Wenn der Username sich ändern kann, kannst Du ja pro User einen eindeutigen Wert (nicht die ID) erzeugen und den verwenden.
Der darf sich dann nicht mehr ändern und dient nur als Username-Ersatz, weil der Name ja geändert werden kann.
Es darf nicht die ID sein, weil dieser Wert über nach Außen sichtbar sein wird.

Wenn der User sich nun anmelden will, meldet der Client das beim Server und bekommt einige Infos zurück:
- Der fest hinterlegte Wert, mit dem das Passwort zuerst gesalzen wurde
- Einen zufälligen Wert, den der Server sich für den User gemerkt hat
Der Client nimmt dann das Passwort, erzeugt einen Hash, gesalzen mit dem ersten Wert. Anschließend erzeugt es einen zweiten Hash, gesalzen mit dem zweiten Wert.
Wenn ich eine Methode "CreateHash" habe, die zwei Strings (Passwort und Salz) entgegen nimmt und den Hash als String zurück gibt, dann würde das so aussehen:
ausblenden C#-Quelltext
1:
2:
3:
4:
var password = //...
var staticSalt = //...
var temporarySalt = //...
var hash = CreateHash(CreateHash(password, staticSalt), temporarySalt);

Auf dem Server nimmst Du den Hash aus der Datenbank, erzeugst davon einen neuen Hash mit dem zweiten temporären Salz-Wert und vergleichst ihn mit dem Hash vom Client.
ausblenden C#-Quelltext
1:
2:
3:
4:
var hashFromClient = //...
var hashFromDatabase = //...
var temporarySalt = //...
var isCorrect = hashFromClient == CreateHash(hashFromDatabase, temporarySalt);


Wie die CreateHash-Methode aussieht, weiß ich jetzt aber auch nicht :D
Es würde an sich ja schon reichen, wenn die beiden String-Parameter nur aneinander gekettet werden.
Wichtig ist nur, dass der Hash bei gleichen Ausgangs-Strings trotzdem anders aussieht.



Ich hab mir das gerade aus den Fingern gesaugt und so noch nie umgesetzt.
Über Feedback wäre ich daher froh :)
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Mo 14.11.16 19:43 
Wie genau meinst du gesalzen? Meinst du dass die einzelnen Buchstaben des Usernamen quer in das Passwort gemixt werden? Oder einfach nur angehängt?
Ich würde es lieber mit einer Zufallszahl machen, dass bsp. das aktuelle Datum vor das plain Passwort gehängt wird und eine Zufallszahl nach dem Passwort. Dann wird das zum Server geschickt, welcher dann auch den Hash aus der Datenbank modifiziert. Dann müsste es ja auch funktionieren, aber dann wird das plain Passwort gecrypted zum Server gesendet. Ist ja auch nicht soo sicher.
Aber das ist mir im Moment noch zu kompliziert, Palladin :|

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Mo 14.11.16 20:30 
user profile iconCsharp-programmierer hat folgendes geschrieben Zum zitierten Posting springen:
also beispielsweise so: 14112015216253716235diesisteinpasswort123wer89w7e78w6er?

Und dann wird das Datum und die Zufallszahl in der PHP Datei einfach vorne bzw. hinten angehängt und dann über Passwort verify geckeckt?

Nein, nicht direkt. Du hast da ja das Passwort einfach rein geschrieben ich sehe da kein hashing. Ich meine schon einen richtigen, kryptografischen Hash.

user profile iconCsharp-programmierer hat folgendes geschrieben Zum zitierten Posting springen:
Und wenn sich dann 2 Administratoren gleichzeitig anmelden, gibt es dann keine Probleme? Wenn man in C# eine Zufallszahl generiert, dann wird immer die selbe Reihenfolge ausgegeben, kann das hier zum Verhängnis werden?

Neee, das ist hier nicht so wichtig. Es geht vor allem darum, dass nicht einfach jemand anderes (der die Antwort abfängt) dieselbe Antwort nochmal schickt und ebenfalls erfolgreich eingeloggt ist.

Nachdem ich deine anderen Beitrage gefunden habe, gehe ich davon aus, dass du in PHP bereits password_hash() benutzt. Das macht es etwas komplexer.
Ich kann dir den Algorithmus gern erklären, aber du musst dann manuell das Datenbank-Feld auswerten, und die hashes vergleichen. (Also PHPs password_verify nachprogrammieren)

Ich glaube, es wäre weniger Aufwand (mit erheblichem Zusatznutzen), wenn du eine TLS-Verschlüsselung implementierst. Auf C#-Seite brauchst du dann vermutlich nur https:// vor die URL schreiben. Für den Server benötigst du ein Zertifikat.
Andere Möglichkeit wäre, das Passwort auf dem Client asymmetrisch zu verschlüsseln, so dass es nur der Server wieder lesen kann.


@Palladin: Mit der PHP-Funktion password_hash() wird bereits ein salt generiert und gespeichert. Es ist also nicht nur ein Hash in der Datenbank sondern sowas wie "$2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F."
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mo 14.11.16 20:55 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Mit der PHP-Funktion password_hash() wird bereits ein salt generiert und gespeichert. Es ist also nicht nur ein Hash in der Datenbank sondern sowas wie "$2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F."


Wie wird der denn gespeichert?
Es muss den Salt ja irgendwie in Verbindung mit dem Passwort speichern, damit beim Vergleichen wieder darauf zurück gegriffen werden kann.

Außerdem fand ich den Gedanken ganz gut, dass der zweite temporäre Salt selber verwaltet wird. Der kann dann z.B. nach 10 Minuten auch wieder gelöscht werden, es bringt also nichts, wenn man die Login-Daten abfängt, der Salt existiert dann nicht mehr.

user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Andere Möglichkeit wäre, das Passwort auf dem Client asymmetrisch zu verschlüsseln, so dass es nur der Server wieder lesen kann.


Das würde ich allerdings nicht machen.
Schließlich muss irgendwo auf dem Server dann der PrivateKey zu finden sein, mit dem dann jedes Passwort entschlüsselt werden kann - keine schöne Vorstellung ...
Oder es wird nur der Hash verschlüsselt, der übertragen wird. Dann interessiert es nicht (zumindest nicht mehr als sonst), wenn jemand den Server gekapert hat, die Passwörter liegen ja immer noch nur als Hash vor. Aber niemand kann die Login-Abfrage speichern und später nochmal raus schicken.

user profile iconCsharp-programmierer hat folgendes geschrieben Zum zitierten Posting springen:
Wie genau meinst du gesalzen?


Von Wikipedia (Salt (Kryptologie)):
Zitat:
Salt (englisch für Salz) bezeichnet in der Kryptographie eine zufällig gewählte Zeichenfolge, die an einen gegebenen Klartext vor der Verwendung als Eingabe einer Hashfunktion angehängt wird, um die Entropie der Eingabe zu erhöhen.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Mo 14.11.16 21:26 
Oder man legt in der Datenbank noch ein neues Feld an, was den SaltKey darstellt. Dieses Feld kann man ja in einem bestimmten Abstand ändern lassen. Bsp. dass ein Admin alle Salts neu generieren lässt. Aber mein Problem ist nun, wie kann man das Passwort, was ein User eingibt, noch mehr verschlüsseln als nur hashen? Dann ist gewährleistet, dass wenn ein Hacker den Salt rausbekommt, dieser Salt wieder geändert wird, oder? Wäre ja fast zu genial.

Zitat:
Nachdem ich deine anderen Beitrage gefunden habe, gehe ich davon aus, dass du in PHP bereits password_hash() benutzt. Das macht es etwas komplexer.
Ich kann dir den Algorithmus gern erklären, aber du musst dann manuell das Datenbank-Feld auswerten, und die hashes vergleichen. (Also PHPs password_verify nachprogrammieren)

Man könnte ja das plain Passwort über den aktuellen Salt verschlüsseln und dann verschlüsselt zu dem PHP Script senden.
Das Problem liegt ja jetzt (so wie ich es verstehe) nur darin, dass man das Passwort sicher dem Server übergeben muss, oder?

Edit: Eine mini Frage am Rand: wenn man in der PHP Datei $conn->close(); aufruft, wird das dann sicher? Bzw. sollte man das machen? Wenn ja, reicht das am Ende bei verschiedenen IF Abfragen?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Mo 14.11.16 21:49 
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Mit der PHP-Funktion password_hash() wird bereits ein salt generiert und gespeichert. Es ist also nicht nur ein Hash in der Datenbank sondern sowas wie "$2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F."


Wie wird der denn gespeichert?
Es muss den Salt ja irgendwie in Verbindung mit dem Passwort speichern, damit beim Vergleichen wieder darauf zurück gegriffen werden kann.

Steckt da mit drin. die ersten 22 Zeichen nach dem $11$ sind der Salt, alles danach ist der Hash des Passworts. Guck mal hier: php.net/manual/de/fu...on.password-hash.php

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Außerdem fand ich den Gedanken ganz gut, dass der zweite temporäre Salt selber verwaltet wird. Der kann dann z.B. nach 10 Minuten auch wieder gelöscht werden, es bringt also nichts, wenn man die Login-Daten abfängt, der Salt existiert dann nicht mehr.

Das aktuelle Problem ist doch, dass wir einerseits das Klartextpasswort nicht übertragen sollen, andererseits müssen wir es serverseitig der Funktion passord_verify() im Klartext übergeben.

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Andere Möglichkeit wäre, das Passwort auf dem Client asymmetrisch zu verschlüsseln, so dass es nur der Server wieder lesen kann.

Das würde ich allerdings nicht machen.
Schließlich muss irgendwo auf dem Server dann der PrivateKey zu finden sein, mit dem dann jedes Passwort entschlüsselt werden kann - keine schöne Vorstellung ...

Du müsstest natürlich vorher die Übertragung mitschneiden, aber stimmt, ist nicht optimal. (In der Datenbank sind ja gesalzene hashes)

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Oder es wird nur der Hash verschlüsselt, der übertragen wird. Dann interessiert es nicht (zumindest nicht mehr als sonst), wenn jemand den Server gekapert hat, die Passwörter liegen ja immer noch nur als Hash vor. Aber niemand kann die Login-Abfrage speichern und später nochmal raus schicken.

Wenn du nur Hashes übertragst, kannst du es am Server wieder nicht gegen den Hash in der Datenbank prüfen.

user profile iconCsharp-programmierer hat folgendes geschrieben Zum zitierten Posting springen:
Oder man legt in der Datenbank noch ein neues Feld an, was den SaltKey darstellt. Dieses Feld kann man ja in einem bestimmten Abstand ändern lassen. Bsp. dass ein Admin alle Salts neu generieren lässt. Aber mein Problem ist nun, wie kann man das Passwort, was ein User eingibt, noch mehr verschlüsseln als nur hashen? Dann ist gewährleistet, dass wenn ein Hacker den Salt rausbekommt, dieser Salt wieder geändert wird, oder? Wäre ja fast zu genial.

Klingt gerade alles andere als genial. Normal ist wie folgt: Du speicherst in der Datenbank salts und die Ergebnisse von Hash(salt+passwort) wobei die Hash-Funktion bspw. bcrypt2 ist.
Den salt kannst du nur sinnvoll ändern, wenn du das Passwort kennst! Denn du musst ja den gespeicherten Hash auch wieder an den Salt anpassen, damit du den Benutzerauthentifizieren kannst. Salts sind nicht geheim

user profile iconCsharp-programmierer hat folgendes geschrieben Zum zitierten Posting springen:
Man könnte ja das plain Passwort über den aktuellen Salt verschlüsseln und dann verschlüsselt zu dem PHP Script senden.
Das Problem liegt ja jetzt (so wie ich es verstehe) nur darin, dass man das Passwort sicher dem Server übergeben muss, oder?

Es sollte halt nicht das Passwort im Klartext übertragen werden, und sinnvollerweise sollte die Übertragung auch gegen Replay-Angriffe abgesichert sein.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mo 14.11.16 22:14 
Zitat:
Steckt da mit drin. die ersten 22 Zeichen nach dem $11$ sind der Salt, alles danach ist der Hash des Passworts.

Was zu dem Problem führt, dass - wie DU ja schon schreibst - das Passwort irgendwie auf dem Server in Klartext auftauchen muss:
Zitat:
Das aktuelle Problem ist doch, dass wir einerseits das Klartextpasswort nicht übertragen sollen, andererseits müssen wir es serverseitig der Funktion passord_verify() im Klartext übergeben.

Da frage ich mich, ob die PHP-Methoden hier überhaupt die richtige Wahl sind?
Für mich klingt das eher so, dass die für eine reine Server-Anwendung gedacht sind, wo die Daten im Prinzip Automatisch aus der form heraus über eine verschlüsselte Verbindung übertragen werden.
Ist es dann nicht sicherer, diese beiden Methoden nicht zu verwenden und einen eigenen Weg zu wählen? Dann muss das Passwort nicht im Klartext übertragen werden, egal ob verschlüsselt oder nicht.

Daher ja der Vorschlag, den ersten Salt, mit dem das Passwort in der Datenbank gesalzen wird, selber zu generieren.
Dieser Salt kann ja bedenkenlos zum Client gesendet werden, ist ja nicht geheim.

Danach greift dann der zweite Vorschlag (was ja im Prinzip deine Idee war) einen zweiten Salt zu generieren und den mit zum Client zu senden, damit weder Klartext-Passwort noch der Passwort-Hash, wie er in der Datenbank steht, übertragen werden muss.

In der Datenbank wird das Passwort also mit Salt1 gesalzen gehashed abgelegt.
Übertragen wird der Hash, der in Verbindung mit Salt 1 erzeugt wurde, nochmal mit Salt2 gesalzen und so zum Client geschickt.
Will da jemand mit lauschen, bekommt er einen Hash, der für eine bestimmte Zeit oder bis zum nächsten Login-Versuch gültig ist.
Danach ist der komplett nutzlos.
Gelangt ein Angreifer auf den Server, findet er dort ebenfalls nur Hashes vor, die einzeln nutzlos sind, da sie mit einem zufälligen (oder eindeutigen) Wert gesalzen wurde und dadurch auch auf anderen Servern nicht genutzt werden kann.
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Mo 14.11.16 22:48 
Ich glaube, ich hab da etwas, was mit der PHP-Funktion zusammen funktioniert.
Im Grunde muss der Client ja nur nachweisen, dass er in der Lage ist den Hash in der Datenbank zu produzieren :idea:

Demzufolge könnte man das etwa so lösen:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
            using (var client = new HttpClient())
            {
                var responseString = client.GetStringAsync("http://DeinServer/RequestAuth?username=Admin");

                /* PHP:
                  $passwordHash = get_hash_from_db;
                  if (substr($passwordHash, 0, 4) === "$2y$") / Nur dann ists sicher
                  {
                    $cryptAndSalt = substr($passwordHash, 0, 29); // der Teil ohne Hash darf nach draußen
                    $nonce = mt_rand();
                    $t = time();
                    // Alles gut definieren (encoding!) und in die Datenbank schreiben.
                    mysqli_query(..., 'insert into login_requests values($cryptAndSalt, $nonce, $t, $username)')
                    $id = mysqli_insert_id ( $conn )
                    // Und die id in der antwort mitschicken, irgendwie als JSON oder so
                  }
                */

                // Das hier kommt jetzt natürlich aus der Antwort von PHP
                string cryptAndSalt = @"$2y$10$.vGA1O9wmRjrwAVXD98HNO";
                int nonce = 42// 4 Bytes
                int t = 133425;
                int id = 3;

                // Jetzt die Benutzereingabe zum Hash verwurschteln. Nuget-Paket "CryptSharpOfficial" hilft
                string texteingabe = @"rasmuslerdorf";
                var fullHash = Crypter.Blowfish.Crypt(texteingabe, cryptAndSalt);
                // Das ist der gleiche Wert, der in der Datenbank stehen müsste. Kann gehasht zum Server

                string zusammengeführt = fullHash + nonce.ToString() + t.ToString() + id.ToString();

                byte[] data = Encoding.UTF8.GetBytes(zusammengeführt);
                byte[] result;
                System.Security.Cryptography.SHA384 shaM = new System.Security.Cryptography.SHA384Managed();
                var allHashed = shaM.ComputeHash(data);

                // Hier musst du dir überlegen, wie du die bytes schön in PHP reinbekommst. HEX-Encoding wäre was, oder base64
                responseString = client.GetStringAsync("http://DeinServer/RequestLogin?id=3&data=xxxxxxxxxxxxxxxxxxxxxx");

                /* PHP
                 $request = mysqli_query(..., 'select * from login_requests where id = $id');
                 $original_hash = mysqli_query(..., 'select hash from users where username = $request[username]');

                 1. Die Daten genau so zusammen führen wie in C'
                 $merged = $original_hash + $request[nonce] +  $request[t] + $id
                 if (sha384($merged) === $data)
                 {
                    // Logged in
                 }
                    
                 */


Du musst allerdings etwas aufpassen: Bytes und strings sind da etwas gemischt, gerade bei dem Teil "cryptAndSalt". Aufpassen mit dem Encoding.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Di 15.11.16 17:00 
Die erste PHP Datei:
ausblenden PHP-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
$Administrator = mysqli_real_escape_string($conn$_GET["username"]);
    $result = mysqli_query($conn"SELECT `Passwort` FROM Administratoren WHERE Username='$Administrator'");
    if($result)
    {
      while($row = mysqli_fetch_assoc($result))
      {
        $hashPasswort = $row["Passwort"];
      }
      
      if(substr($hashPasswort04) === "$2y$")
      {
        $CryptAndSalt = substr($hashPasswort029);
        $nonce = mt_rand();
        $t = time();

        mysqli_query($conn"INSERT INTO `login_request`(`CryptAndSalt`, `nonce`, `time`, `username`) VALUES ('$CryptAndSalt', '$nonce', '$t', '$Administrator'");
        $id = mysqli_insert_id($conn);
        
        echo $CryptAndSalt";"$nonce";"$t";"$id;
      }        
    }

2. PHP Datei
ausblenden PHP-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
$id = mysqli_real_escape_string($conn$_GET["id"]);
    $username = mysqli_real_escape_string($conn$_GET["username"]);
    
    $request = mysqli_query($conn"SELECT *FROM `login_request` where id='$id'");
    $originalHash = mysqli_query($conn"SELECT passwort FROM Administratoren where username='$username'");
    
    $merged = $originalHash + $request["nonce"] + $request["t"] + $id;
    if(sha384($merged) === $_GET["data"];
    {
      echo "success";
    }
    else
    {
      echo "denied.";
    }


Und der C# Quelltext
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
using (var client = new HttpClient())
            {
                string crypSalt = "";
                int nonce = 0;
                int t = 0;
                int id = 0;

                _URL = "http://dieurl/AdministratorLogin.php?username=" + this.textBox1.Text;
                var responseString = client.GetStringAsync(_URL);

                string[] ServerResult = responseString.Result.Split(';');
                crypSalt = ServerResult[0];
                nonce = int.Parse(ServerResult[1]);
                t = int.Parse(ServerResult[2]);
                id = int.Parse(ServerResult[3]);

                string TextEingabe = this.textBox2.Text;
                var fullHash = CryptSharp.Crypter.Blowfish.Crypt(TextEingabe, crypSalt);
                string Zusammengeführt = fullHash + nonce.ToString() + t.ToString() + id.ToString();

                byte[] data = Encoding.UTF8.GetBytes(Zusammengeführt);
                byte[] result;
                System.Security.Cryptography.SHA384 shaM = new System.Security.Cryptography.SHA384Managed();
                var allHashed = shaM.ComputeHash(data);

                responseString = client.GetStringAsync("http://dieurl/RequestLogin.php?username=" + this.textBox1.Text + "&id=" + this.textBox1.Text + "&data=" + data.ToString());
            }


Ich habe 2 Tabellen. Auf der einen `Administratoren` sind alle Admins, mit den gehashten Passwörtern und anderen Information. Eine andere Tabelle habe ich eben für ein Beispiel angelegt. Die hat die Datenfelder ID, Salt, nonce, t und username. In der C# Applikation kommt der Fehler hier:
var fullHash = CryptSharp.Crypter.Blowfish.Crypt(TextEingabe, crypSalt);

Als Fehlermeldung kommt dann ArgumentException. In der textbox2 befindet sich das passwort :(

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 15.11.16 23:12 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Mi 16.11.16 20:54 
Und wo bekomme ich jetzt ein Argument vom Typ Byte her? Einfach das Passwort in ein Byte konvertieren? Oder muss ich da ein anderes Argument nehmen?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 16.11.16 21:20 
- Nachträglich durch die Entwickler-Ecke gelöscht -
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Do 17.11.16 23:11 
Das geht ja beispielsweise per
ausblenden C#-Quelltext
1:
Encoding.UTF8.GetBytes(zusammengeführt);					


Die Encoding Klasse stellt diverse Kodierungen bereit. Bitte denke aber immer daran, dass sowohl der Weg von String zu Bytes als auch der Weg von Bytes zu String IMMER ein Encoding beinhaltet. Manchmal ist es implizit oder es gibt einen Standardwert, aber es ist immer da.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Sa 19.11.16 20:04 
So ich habe mich jetzt entschieden, die Website über https:// zu schäutzen. Mir schwebt dieses Zertifikat vor: alfahosting.de/ssl-zertifikate-vergleich/
Das erste für 1,69€

Wenn ich dieses Zertifikat kaufe, müsste ja in der URL dann auch https:// grün eingefärbt sein. Wenn ich die Daten über die C# Applikation so versende, wie ich es bis jetzt mache, gibt es dann Probleme? Weil irgendwie müssen die Daten ja dann verschlüsselt übertragen werden. Muss ich da noch irgendwie was machen oder macht der Server das automatisch? Und ist dann auch sichergestellt, dass kein dritter die Daten über WireShark oder sowas mitlesen kann?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 19.11.16 20:41 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Sa 19.11.16 21:25 
Also dort steht ja, dass die beiden PCs sich auf einen Algorithmus einigen, bevor die eigentlichen Daten ausgetauscht werden. Das heißt, dass ich nichts extra programmieren muss, sondern das voll automatisch abläuft?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Do 01.12.16 21:30 
Jetzt habe ich auf https:// ausgrüstet. Trotzdem möchte ich, dass man eine Aktion bei dem Server erst anmelden muss. Es gibt verschiedene PHP Scripte, die alle Daten an die C# Anwendung rausgeben. Da wäre es ja blöd, wenn diese in falsche Hände kommen. Geht das irgendwie, dass die PHP Datei Zahlen generiert, die nur die Admins wissen? Oder dass man diesen Prozess sicherer macht?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein