3.1 Benutzerkonto schützen


In den letzten Jahren gab es den Trend, dass für eine digitale Dienstleistung beim Anbieter ein Konto angelegt wird. Selbst bei Betriebssystemen wie IOs oder Windows soll ein Online-Konto angelegt werden, damit die digitalen Dienstleistungen genutzt werden können. Die Anzahl der Benutzerkonten, die man nutzt, steigt schnell stark an.

Oft empfinden es viele Benutzer als zu mühsam, sich für jedes Konto eine neue Kombination aus Benutzernamen und Passwort auszudenken und zu merken/zu notieren. Viele schützen daher ihre Konten mit dem immer gleichen Passwort. Auf Wikipedia findet man eine Liste der am häufigsten verwendeten Passwörter: Wikipedia .

Ein Konto, das mit einem solchen Passwort versehen ist, gilt als nicht geschützt. Sollte ein Hacker ein solches unsicheres Passwort herausfinden und das immer gleiche Passwort wird bei vielen Online-Konten genutzt, wird man digital verletzbar.

Ein Passwort wird auf dem Server nicht im Klartext gespeichert, sondern in einer codierten Form, dem Hash-Code.

Für das Passwort

123456

liefert z.B. der MD5-Hash-Algorithmus folgenden Hash-Code:

e10adc3949ba59abbe56e057f20f883e

Autor: Joseph Myers
Quelle: md5.js

    function md5cycle(x, k) {
      var a = x[0], b = x[1], c = x[2], d = x[3];

      a = ff(a, b, c, d, k[0], 7, -680876936);
      d = ff(d, a, b, c, k[1], 12, -389564586);
      c = ff(c, d, a, b, k[2], 17,  606105819);
      b = ff(b, c, d, a, k[3], 22, -1044525330);
      a = ff(a, b, c, d, k[4], 7, -176418897);
      d = ff(d, a, b, c, k[5], 12,  1200080426);
      c = ff(c, d, a, b, k[6], 17, -1473231341);
      b = ff(b, c, d, a, k[7], 22, -45705983);
      a = ff(a, b, c, d, k[8], 7,  1770035416);
      d = ff(d, a, b, c, k[9], 12, -1958414417);
      c = ff(c, d, a, b, k[10], 17, -42063);
      b = ff(b, c, d, a, k[11], 22, -1990404162);
      a = ff(a, b, c, d, k[12], 7,  1804603682);
      d = ff(d, a, b, c, k[13], 12, -40341101);
      c = ff(c, d, a, b, k[14], 17, -1502002290);
      b = ff(b, c, d, a, k[15], 22,  1236535329);

      a = gg(a, b, c, d, k[1], 5, -165796510);
      d = gg(d, a, b, c, k[6], 9, -1069501632);
      c = gg(c, d, a, b, k[11], 14,  643717713);
      b = gg(b, c, d, a, k[0], 20, -373897302);
      a = gg(a, b, c, d, k[5], 5, -701558691);
      d = gg(d, a, b, c, k[10], 9,  38016083);
      c = gg(c, d, a, b, k[15], 14, -660478335);
      b = gg(b, c, d, a, k[4], 20, -405537848);
      a = gg(a, b, c, d, k[9], 5,  568446438);
      d = gg(d, a, b, c, k[14], 9, -1019803690);
      c = gg(c, d, a, b, k[3], 14, -187363961);
      b = gg(b, c, d, a, k[8], 20,  1163531501);
      a = gg(a, b, c, d, k[13], 5, -1444681467);
      d = gg(d, a, b, c, k[2], 9, -51403784);
      c = gg(c, d, a, b, k[7], 14,  1735328473);
      b = gg(b, c, d, a, k[12], 20, -1926607734);

      a = hh(a, b, c, d, k[5], 4, -378558);
      d = hh(d, a, b, c, k[8], 11, -2022574463);
      c = hh(c, d, a, b, k[11], 16,  1839030562);
      b = hh(b, c, d, a, k[14], 23, -35309556);
      a = hh(a, b, c, d, k[1], 4, -1530992060);
      d = hh(d, a, b, c, k[4], 11,  1272893353);
      c = hh(c, d, a, b, k[7], 16, -155497632);
      b = hh(b, c, d, a, k[10], 23, -1094730640);
      a = hh(a, b, c, d, k[13], 4,  681279174);
      d = hh(d, a, b, c, k[0], 11, -358537222);
      c = hh(c, d, a, b, k[3], 16, -722521979);
      b = hh(b, c, d, a, k[6], 23,  76029189);
      a = hh(a, b, c, d, k[9], 4, -640364487);
      d = hh(d, a, b, c, k[12], 11, -421815835);
      c = hh(c, d, a, b, k[15], 16,  530742520);
      b = hh(b, c, d, a, k[2], 23, -995338651);

      a = ii(a, b, c, d, k[0], 6, -198630844);
      d = ii(d, a, b, c, k[7], 10,  1126891415);
      c = ii(c, d, a, b, k[14], 15, -1416354905);
      b = ii(b, c, d, a, k[5], 21, -57434055);
      a = ii(a, b, c, d, k[12], 6,  1700485571);
      d = ii(d, a, b, c, k[3], 10, -1894986606);
      c = ii(c, d, a, b, k[10], 15, -1051523);
      b = ii(b, c, d, a, k[1], 21, -2054922799);
      a = ii(a, b, c, d, k[8], 6,  1873313359);
      d = ii(d, a, b, c, k[15], 10, -30611744);
      c = ii(c, d, a, b, k[6], 15, -1560198380);
      b = ii(b, c, d, a, k[13], 21,  1309151649);
      a = ii(a, b, c, d, k[4], 6, -145523070);
      d = ii(d, a, b, c, k[11], 10, -1120210379);
      c = ii(c, d, a, b, k[2], 15,  718787259);
      b = ii(b, c, d, a, k[9], 21, -343485551);

      x[0] = add32(a, x[0]);
      x[1] = add32(b, x[1]);
      x[2] = add32(c, x[2]);
      x[3] = add32(d, x[3]);
    }

    function cmn(q, a, b, x, s, t) {
      a = add32(add32(a, q), add32(x, t));
      return add32((a << s) | (a >>> (32 - s)), b);
    }

    function ff(a, b, c, d, x, s, t) {
      return cmn((b & c) | ((~b) & d), a, b, x, s, t);
    }

    function gg(a, b, c, d, x, s, t) {
      return cmn((b & d) | (c & (~d)), a, b, x, s, t);
    }

    function hh(a, b, c, d, x, s, t) {
      return cmn(b ^ c ^ d, a, b, x, s, t);
    }

    function ii(a, b, c, d, x, s, t) {
      return cmn(c ^ (b | (~d)), a, b, x, s, t);
    }

    function md51(s) {
      txt = '';
      var n = s.length,
      state = [1732584193, -271733879, -1732584194, 271733878], i;
      for (i=64; i<=s.length; i+=64) {
        md5cycle(state, md5blk(s.substring(i-64, i)));
      }
      s = s.substring(i-64);
      var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
      for (i=0; i<s.length; i++) tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3);
      tail[i>>2] |= 0x80 << ((i%4) << 3);
      if (i > 55) {
        md5cycle(state, tail);
        for (i=0; i<16; i++) tail[i] = 0;
      }
      tail[14] = n*8;
      md5cycle(state, tail);
      return state;
    }

    function md5blk(s) { 
      var md5blks = [], i;
        for (i=0; i<64; i+=4) {
          md5blks[i>>2] = s.charCodeAt(i) + (s.charCodeAt(i+1) << 8)
            + (s.charCodeAt(i+2) << 16) + (s.charCodeAt(i+3) << 24);
        }
      return md5blks;
    }

    var hex_chr = '0123456789abcdef'.split('');

    function rhex(n)
    {
      var s='', j=0;
      for(; j<4; j++) s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
        + hex_chr[(n >> (j * 8)) & 0x0F];
      return s;
    }

    function hex(x) {
      for (var i=0; i<x.length; i++) x[i] = rhex(x[i]);
      return x.join('');
    }

    function md5(s) {
      return hex(md51(s));
    }

    function add32(a, b) {
      return (a + b) & 0xFFFFFFFF;
    }

    if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
      function add32(x, y) {
        var lsw = (x & 0xFFFF) + (y & 0xFFFF),
        msw = (x >> 16) + (y >> 16) + (lsw >> 16);
        return (msw << 16) | (lsw & 0xFFFF);
      }
    }

Auf dem Server ist der Hashcode eines Passworts gespeichert. Wird ein Server gehackt, kann ein:e Hacker:in nur die gespeicherten Hashcodes der Passwörter auslesen.

In einem neuen Tab öffnen: Hash-Codierung

Je nach Anbieter können unterschiedliche Algorithmen zur Erzeugung solcher Hash-Codes verwendet werden. Es gibt sehr viele unterschiedliche Algorithmen zur Erzeugung von Hash-Codes: Hash-Algorithmen. Alle diese Algorithmen haben gemeinsam, dass es nicht möglich ist aus dem Hash-Code das Passwort zu rekonstruieren.

Hacker gehen anders vor. Sie lassen umfangreiche Datenbanken von Hash-Codes für die am häufigsten verwendeten Passwörter vom Computer erzeugen. Wenn ein Server gehackt wurde und man die Passwort-Datenbank ausliest, dann sehen Hacker nur die Hash-Codes der Passwörter. Diese werden mit den Hash-Code-Datenbanken verglichen. Bei einer Übereinstimmung ist das Passwort gehackt worden, denn der Klartext ist nun bekannt.

Beispiel:

Md5(1234) = 81dc9bdb52d04dc20036dbd8313ed055
Md5(123456789) = 25f9e794323b453885f5181f1b624d0b
Md5(12345) = 827ccb0eea8a706c4c34a16891f84e7b
Md5(qwerty) = d8578edf8458ce06fbc5bb76a58c5ca4
Md5(Kennwort) = 98176b7da95f6fd994fe285e06241163
Md5(12345678) = 25d55ad283aa400af464c76d713c07ad
Md5(111111) = 96e79218965eb72c92a549dd5a330112
Md5(123123) = 4297f44b13955235245b2497399d7a93
Md5(1234567890) = e807f1fcf82d132f9bb018ca6738a19f

usw. ...

Wird der Hash-Code "827ccb0eea8a706c4c34a16891f84e7b" im gehackten Server gefunden, dann weiß der Hacker, dass dieser Benutzer das Passwort "12345" verwendet. Wenn der Benutzer dieses Passwort auch bei anderen digitalen Dienstleistern verwendet, können seine Konten angegriffen werden.

Damit das Passwort nicht rekonstruiert werden kann, darf das Passwort nicht in der Hacker-Datenbank vorhanden sein. Die Wahrscheinlichkeit dafür ist um so größer, je länger oder je komplizierter das Passwort ist.

Kurze Rechnung: Wenn alle Zeichen der Tastatur inklusive Groß- und Kleinschreibung verwendet werden, dann gibt es ca. 100 unterschiedliche Zeichen.

  • Ist ein Passwort 5 Zeichen lang, dann gibt es \(100^5 = 10.000.000.000\) Möglichkeiten. Alle möglichen Hashcodes rechnet ein Computer in wenigen Sekunden aus.
  • Ist ein Passwort 10 Zeichen lang, dann gibt es \(100^{10} = 1 \cdot 10^{20}\) Möglichkeiten. Da wäre ein Computer schon lange beschäftigt und man bräuchte etliche Festplatten um alle Hashcodes zu speichern.
  • ...

Ein sicheres Passwort ist also ein Passwort, bei welchem die Wahrscheinlichkeit gering ist, dass es in einer Hacker-Datenbank enthalten ist. Dafür gibt es statistisch also zwei Möglichkeiten. Das Passwort ist:

  • sehr lang (IchBinHeuteEchtGutDraufWeilDieSonneScheint) oder
  • kompliziert und mittellang (5%gHufe!!47&12).

Je schneller die Computer werden, desto länger und komplizierter sollten die Passwörter werden.

Ein Brute-Force-Angriff ist eine Angriffsmethode bei der durch reines Ausprobieren versucht wird, sich bei einem Konto anzumelden:

  • In der Anmeldemaske wird ein zufällig generiertes Passwort eingetragen und die Anmeldung versucht.
  • Das wird solange wiederholt, bis man erfolgreich angemeldet ist.

Manche Webseiten schützen sich vor solchen Angriffen, indem bei einer Anmeldung zusätzlich ein Captcha angegeben werden muss, damit nur Menschen die Anmeldung vornehmen können.

Beispiel: Google recaptcha