Passwort-Sicherheit & Basic Kryptologie

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Es gibt Neuigkeiten! Ab sofort könnt ihr dem Donators Club auf Lebenszeit beitreten.
    Weitere Infos im Thema Donator's Club ab heute wieder verfügbar!

    • Passwort-Sicherheit & Basic Kryptologie

      Hey Leute,

      ich wollte euch ganz kurz in die Basics der Kryptologie einführen, da scheinbar einige das mit den Passwörtern noch nicht verstanden haben ^^

      Erst einmal klären wir ein paar Fachbegriffe:

      Einwegfunktionen
      Eine "echte" Einwegfunktion verändert einen Wert und lässt ihn (offiziell) nicht wieder zurückrechnen
      Ein (schlechtes) Beispiel ist z.B.

      Quellcode

      1. neuerwert = (alterwert * 2) ^ (alterwert / 5)
      Aus dem alten Wert lässt sich ruck-zuck ein neuer Wert berechnen, anders herum kann es zu Schwierigkeiten kommen und man müsste mit Raten anfangen...
      Für die, die mir nicht glauben: neuerwert = 4,3125 Wer das zurückrechnet, dem schicke ich per Post einen Lollie :D

      Einwegfunktionen mit Falltür In diesem Beispiel: Public-Key-Verfahren
      Nun gibt es einige Einwegfunktionen, die man doch zurückrechnen kann, aber nicht so, wie man sie berechnet hat.
      Das mag jetzt kompliziert klingen (ist es auch), aber ich stelle das mal bildlich da, erkläre das dann danach:
      • Ihr habt eine Poststelle (o.ä.) an der jeder eine Eisenkasette hat
      • Wollt ihr etwas verschlüsseln, macht ihr die Kasette zu und lasst das Schloss einklicken.
      • Nun kann niemand mehr an den Inhalt rein (außer er nutzt Gewalt, aber wir gehen von netten Leuten aus)
      • Der, dem die Kassette gehört, geht nun in die Poststelle, öffnet die Kasette mit seinem Schlüssel und hat den Inhalt vorliegen

      Ein tägliches Beispiel davon, und genau davon, finden wir täglich: HTTP mit SSL ( https )
      Beim Public-Key-Verfahren gibt es einen Public-Key und einen Private-Key. Der Public-Key ist öffentlich bekannt und das Schloss der Kassette, der Private-Key der Schlüssel.

      Hash
      Ein Hash ist eine Einwegfunktion. Das bedeutet, man kann ihn nicht zurückberechnen, man kann aber "probieren"

      Salts ( Salz )
      Salts sind noch mal ein Aufsatz auf den Hash, weil dabei 2 "Passwörter" existieren - eines wird vom Server bei der ersten Erstellung des Accountes erstellt, das andere kommt von Benutzer.
      Dann werden beide aneinander gehängt und gehasht. Davon der Hash und der Salt werden gespeichert.
      Beispiel:

      Quellcode

      1. Benutzerpasswort: helloworld
      2. Salt: kdbjyhbfdxkjyhxdbkjsf
      3. Vor dem Hash: helloworldkdbjyhbfdxkjyhxdbkjsf
      4. Gehasht: hdhggksdhfmkfudjdyuhglgfj
      Gespeichert wird der Salt und "Gehasht", dann wird das jedes mal neu zusammengesetzt.
      Der Vorteil von Salts liegt darin, dass ein (hoffentlich nicht) Hacker die Hash-Summen nicht einfach in einer großen Datenbank nachschlägt, da der gesaltete Hash von dem normalen Hash unterscheidet.

      Pepper ( Pfeffer )
      Der Pepper ist im Prinzip ein "globaler Salt", der für alle Accounts gleich ist und, genau wieder Salt, optional alleine oder in Verbindung mit ihm genutzt werden kann. Pfeffer und Salz ergänzen sich prima, da, sollte jemand Zugriff auf die Datenbank haben, er den Pepper nicht kennt, sollte er ihn aber kennen und in den Jahren vor dem Hack eine Datenbank mit dem Pepper angelegt haben über den Salt stolpert. Außerdem macht er den String vor dem Hashen noch etwas länger :whistling:

      Kollisionen
      Kollisionen existieren, wenn 2 Werte den selben Hash haben. Eine Beispiel-Kollision für MD5:

      Quellcode

      1. d131dd02c5e6eec4693d9a0698aff95c
      2. 2fcab5[b]8[/b]712467eab4004583eb8fb7f89
      3. 55ad340609f4b30283e4888325[b]7[/b]1415a
      4. 085125e8f7cdc99fd91dbd[b]f[/b]280373c5b
      5. d8823e3156348f5bae6dacd436c919c6
      6. dd53e2b487da03fd02396306d248cda0
      7. e99f33420f577ee8ce54b67080a80d1e
      8. c69821bcb6a8839396f9652b6ff72a70
      9. d131dd02c5e6eec4693d9a0698aff95c
      10. 2fcab5[b]0[/b]712467eab4004583eb8fb7f89
      11. 55ad340609f4b30283e4888325[b]f[/b]1415a
      12. 085125e8f7cdc99fd91dbd[b]7[/b]280373c5b
      13. d8823e3156348f5bae6dacd436c919c6
      14. dd53e23487da03fd02396306d248cda0
      15. e99f33420f577ee8ce54b67080280d1e
      16. c69821bcb6a8839396f965ab6ff72a70
      Alles anzeigen
      Nun ist es sehr unwarscheinlich, dass ein anderer Benutzer just dieses Passwort hat, aber wenn man genug Zeit hat kann man zu eigentlich jeden Hash eine Kollision finden

      Verschlüsselung
      Eine Verschlüsselung ist kein Hash !
      Eine Verschlüsselung zeichnet sich dadurch aus, dass man sie wieder entschlüsseln kann - unterschieden wird dabei zwischen symetrisch und asymetrisch. Bei ersteres wird zum Ver- und Entschlüsseln das gleiche Passwort genutzt ( Beispiel: AES ), bei zweiteren sind die Passwörter unterschiedlich ( Beispiel: DES, Public-Key-Verfahren. Natürlich kann man das auch mischen, dass das Passwort asymetrisch gespeichert / gesendet wird und danach auf symetrische verfahren zugegriffen wird ( "Hybride Verschlüsselung" ) - der Vorteil liegt dabei daran, dass man nicht den Geschwindigkeitsverlust von dem asymetrischen Verschlüsselungsverfahren einbüßt, das Passwort sicher übertragen kann und die Verbindung danach auch noch sicher ist.

      Kodierungen
      Eine Kodierung unterscheidet sich von einer Verschlüsselung dadurch, dass die Kodierung kein Passwort hat. Als ein bekanntes Beispiel dient Base64 oder Caesar. Problematisch wird es u.a. bei der Rot-"Verschlüsselung", da dort theoretisch auch ein Passwort genutzt wird, es sich aber schnell erraten lässt - und das Caesar theoretisch auch nur Rot13 ist, könnte man es ja auch als Passwort einstufen :whistling:

      Wie realisiere ich jetzt einen sicheren Login ?
      • Der Benutzer registriert sich und gibt sein Passwort ein.
      • Wir generieren für das Passwort einen Salt und hashen das beides zusammen
      • Gesalteter Hash und Salt kommen in die Datei/Datenbank/...
      • Bei der Passwortabfrage hängen wir an das eingegebene Passwort wieder den Salt an
      • Jetzt hashen wir die zusammenstellung oben und vergleichen das mit dem gesaltenem Hash
      • Stimmt das überein, ist das Passwort richtig
      Als Hilfe dafür habe ich 2 Funktionen definiert (findet ihr gaaaaaanz unten), eine erzeugt einen Salt beliebiger Länge, die andere Hasht den Salt und das Passwort zu beliebiger Länge.
      Beispiel zur Nutzung:

      PAWN-Quellcode

      1. new salt[64];
      2. new pwhash[128];
      3. GenerateSalt(64, salt); // Wir erstellen einen zufälligen Salt für den Benutzer
      4. CreateSaltedHash(inputtext, salt, 128, pwhash); // Wir erstellen einen salted Hash des Passwortes ( inputtext <=> Passwort )
      Wichtig ist, und das wiederhole ich jetzt noch einmal, dass der Salt mitgespeichert wird.
      Denn ein anderer Salt ergibt ein anderen Hash.
      Vergleichen können wir die Passwörter nun folgendermaßen:

      PAWN-Quellcode

      1. new pwhash[128];
      2. CreateSaltedHash(inputtext, PInfo[playerid][pSalt], 128, pwhash); // Wir erstellen einen salted Hash des Passwortes ( inputtext <=> Passwort )
      3. if(strcmp(PInfo[playerid][pSaltedHash], pwhash, false) == 0)
      4. SendClientMessage(playerid, 0xFF00FF, "Du hast dich eingeloggt");
      5. else
      6. SendClientMessage(playerid, 0xFFFF00, "Login falsch");


      MD5
      MD5 ist ein Algorithmus, der sich mittlerweile sehr durchgesetzt hat - wie alle anderen Hashfunktionen lässt auch er sich nicht wieder "zurückumwandeln", es ist aber auch hier möglich, den originalen Wert zu "erraten" ( dauert aber etwas ). MD5 gibt unabhängig von dem normalen Passwort einen 32 Byte langen String zurück der die Zeichen 0 - 9 und a - f / A - F hat.
      Hier findet ihr eine Include von Y-Less, mit der ihr MD5 in SA:MP umsetzen könnt. Empfohlen wird aber auch hier, einen Salt hinzuzuschalten, da es für MD5 wesentlich größere Datenbanken gibt. Ein Beispiel ohne Salt währe folgendes:

      PAWN-Quellcode

      1. new hash[32];
      2. hash = MD5_Hash("test");
      Und mit dem Salt könnte man es wie folgt umsetzen:

      PAWN-Quellcode

      1. new salt[32];
      2. new password[20 + 32]; // 20 Zeichen + 32 Zeichen vom Salt
      3. new hash[32];
      4. GenerateSalt(32, salt);
      5. format(password, sizeof(password), "%s%s", inputtext, salt);
      6. hash = MD5_Hash(password);
      Bei beiden Beispielen haben wir dann in der variable "Hash" den Hash, den wir eintragen. Im Zewiten brauchen wir zusätzlich noch den Salt, den wir speichern ;)

      Auf der Basis meiner Salt- und Hashsysteme unten, die ich übrigens selber geschrieben habe (deswegen hat das auch so lange gedauert :cursing:) könnt ihr übrigens eure eigenen Hashsysteme basteln :)
      Dazu müsst ihr nur das Array erweitern und bei der CreateSaltedHash den 2.ten Operator der Modulorechnung anpassen ;)

      Ich hoffe, ich konnte euch der Passwortsicherheit ein Stücken näher bringen :)

      Tion

      Auch jetzt gilt, wie immer: Fragen sind zum Fragen da, Feedback ist erwünscht (heute auch mal negatives) und Ideen können eingebracht werden


      Hash- und Saltfunktion

      PAWN-Quellcode

      1. forward GenerateSalt(length, salt[]);
      2. public GenerateSalt(length, salt[])
      3. {
      4. new saltchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      5. for(new i = 0; i < length - 1; i++)
      6. {
      7. salt[i] = saltchars[random(strlen(saltchars) - 2) + 1];
      8. }
      9. salt[length - 1] = 0;
      10. return true;
      11. }
      12. forward CreateSaltedHash(string[], salt[], length, dest[]);
      13. public CreateSaltedHash(string[], salt[], length, dest[])
      14. {
      15. new hashchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      16. new c1, c2;
      17. for(new i = 0; i < length - 1; i++)
      18. {
      19. if(c1 >= strlen(string) - 1) c1 = 0;
      20. if(c2 >= strlen(salt) - 1) c2 = 0;
      21. dest[i] = hashchars[(string[c1] * salt[c2]) % 63];
      22. c1++; c2++;
      23. }
      24. dest[length - 1] = 0;
      25. }
      Alles anzeigen
      100.000 Durchgänge brauchen bei einem 16-stelligen Salt und einem resultierendem 16-Stelligen Hash etwa 3 Sekunden.
      Testscript:

      PAWN-Quellcode

      1. #include <a_samp>
      2. #define SALT_LENGTH 16 // Wie lang soll der Salt sein ?
      3. #define HASH_LENGTH 16 // Wie lang soll der Hash sein ?
      4. public OnGameModeInit()
      5. {
      6. new password[20] = "Supersicheres PW";
      7. new salt[SALT_LENGTH] = "hfgthdgtfhgbdgf";
      8. new saltedpw[HASH_LENGTH];
      9. new messungen = 100000;
      10. new tmp = 0;
      11. new gesammt = 0;
      12. for(new i = 0; i < messungen; i+= 10)
      13. {
      14. tmp = GetTickCount();
      15. GenerateSalt(SALT_LENGTH, salt);
      16. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      17. GenerateSalt(SALT_LENGTH, salt);
      18. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      19. GenerateSalt(SALT_LENGTH, salt);
      20. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      21. GenerateSalt(SALT_LENGTH, salt);
      22. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      23. GenerateSalt(SALT_LENGTH, salt);
      24. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      25. GenerateSalt(SALT_LENGTH, salt);
      26. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      27. GenerateSalt(SALT_LENGTH, salt);
      28. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      29. GenerateSalt(SALT_LENGTH, salt);
      30. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      31. GenerateSalt(SALT_LENGTH, salt);
      32. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      33. GenerateSalt(SALT_LENGTH, salt);
      34. CreateSaltedHash(password, salt, HASH_LENGTH, saltedpw);
      35. gesammt += GetTickCount() - tmp;
      36. }
      37. printf("%50s%5d", "Messungen:", messungen);
      38. printf("%50s%5d", "Gesammtzeit:", gesammt);
      39. printf("%50s%5f", "Durchschnitt:", (gesammt / messungen));
      40. return true;
      41. }
      42. main( ) { }
      43. forward GenerateSalt(length, salt[]);
      44. public GenerateSalt(length, salt[])
      45. {
      46. new saltchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      47. for(new i = 0; i < length - 1; i++)
      48. {
      49. salt[i] = saltchars[random(strlen(saltchars) - 2) + 1];
      50. }
      51. salt[length - 1] = 0;
      52. return true;
      53. }
      54. forward CreateSaltedHash(string[], salt[], length, dest[]);
      55. public CreateSaltedHash(string[], salt[], length, dest[])
      56. {
      57. new hashchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      58. new c1, c2;
      59. for(new i = 0; i < length - 1; i++)
      60. {
      61. if(c1 >= strlen(string) - 1) c1 = 0;
      62. if(c2 >= strlen(salt) - 1) c2 = 0;
      63. dest[i] = hashchars[(string[c1] * salt[c2]) % 63];
      64. c1++; c2++;
      65. }
      66. dest[length - 1] = 0;
      67. }
      Alles anzeigen
      Webdesign (bevorzugt backend) • Android-Development • node.js • Pawn • Linux
      Reverse Engineering • Social Engineering • Cryptoanalyse • PGP-Key
      ReferenzenMein Facebook-Acc

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Tion () aus folgendem Grund: MD5, Pfeffer, Verschlüsselung

    • (Wahrscheinlich sind die meisten zu dumm)
      Dies ist ziemlich beleidigend für "die meisten" die du meinst. :thumbdown:
      Einigen Menschen ist es halt zu kompliziert X/
      denke du würdest es auch nicht nett finden wenn man dich dumm nennt nur weil du mal was nicht verstehst.
      Ich bitte dich nächstesmal auf deine wortwahl zu achten
      >> sPa.M << go, go,Bann me, Bann me

    • Gefällt mir, da doch immer wieder Hashes und Verschlüsselungen durcheinander geworfen werden.
      Du erwähnst ja Salts zum "sichereren" Hashen. Du könntest deshalb, auch wenns nicht so wichtig ist, auch noch auf die Pepper und deren Unterschied zu Salts eingehen.
      Aber ansonsten ist das Turorial verständlich und sauber geschrieben.

      edit: lol ich seh grad, dass der Tread schon alt ist. Da hat Hami wohl was ausgegraben :D Naja, schaden tut es sicher nicht.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Hagi ()

    • Hagi schrieb:

      Gefällt mir, da doch immer wieder Hashes und Verschlüsselungen durcheinander geworfen werden.
      Du erwähnst ja Salts zum "sichereren" Hashen. Du könntest deshalb, auch wenns nicht so wichtig ist, auch noch auf die Pepper und deren Unterschied zu Salts eingehen.
      Okay, auch das kann ich machen - obwohl es nur ein paar Wörter dazu zu sagen gibt :D

      Mich wundert es gerade leicht, dass der Thread nach 10 Monaten plötztlich so viel Aufmerksamkeit bekommt ^^
      Webdesign (bevorzugt backend) • Android-Development • node.js • Pawn • Linux
      Reverse Engineering • Social Engineering • Cryptoanalyse • PGP-Key
      ReferenzenMein Facebook-Acc
    • Hagi schrieb:

      was ausgegraben
      Nein, ich fand den Thread hilfreich ;)

      namespace schrieb:

      MD5 ist keine Verschlüssung.
      Oh, wusste ich nicht, naja es verschlüsselt (richtige Wortwahl?) aber ein (Pass-)Wort

      Tion schrieb:

      danke dir :thumbup:
      Kein Problem, wir danken dir ^_^

      Grek schrieb:

      Ich bitte dich nächstesmal auf deine wortwahl zu achten
      Tut mir leid ;(
      One Day Baby, One Day...


      [ FILTERSCRIPT ]
      InGameNPC by Hami - Erstelle InGame NPC's !

    • ==Banger schrieb:

      Ist zwar ein alter Thread aber ich denke der wird noch als Vorblid genutzt. Wieso kennt mein Script die Begriffe wie Hash nicht? Muss ich mir da ein Include downloaden und wenn ja wo und welches?
      In dem Release SA:MP 0.3.7 R1 wurde die Funktion wiki.sa-mp.com/wiki/SHA256_PassHash hinzugefügt. Falls dir diese nicht reicht, musst du auf ein PlugIn wie:
      1. forum.sa-mp.com/showthread.php?t=188734
      2. forum.sa-mp.com/showthread.php?t=570945
      3. ...
      zurückgreifen.