Übergabe von verschlüsselten Variablen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Übergabe von verschlüsselten Variablen

    Um Scripts man-in-the-middle-sicher zu machen, habe ich einen symmetrischen Verschlüsselungsalgorithmus entwickelt, der POST-Variable ermöglicht, die nicht so einfach zu entschlüsseln sind (ohne Kenntnis des Schlüssels eigentlich überhaupt nicht).

    Mich interessiert es, ob es Experten gibt, die die Schwachstellen dieses Verfahrens nennen können.
    Das Prinzip besteht aus einer mehrfachen Codierung des zu verschlüsselnden Strings. Aus dem Schlüssel wird ein MD5 Hash gebildet, der als Schlüssel für die zweite Stufe verwendet wird.
    Weiterhin wird der Schlüssel reversiert und dieser Schlüssel wird als dritter Schlüssel verwendet.
    Um die Sicherheit weiter zu erhöhen, werden zwei Zufallszahlen gebildet. Die erste ist zwischen 1 und der Länge des Schlüssels, die zweite zwischen 1 und 32. Mit Hilfe dieser Zufallszahlen werden die Schlüssel modifiziert.
    Wenn beispielsweise der Schlüssel 50 Stellen hat und die erste Zufallszahl 18 ist, dann wird der verwendete Schlüssel aus Position 18-50 und aus Position 1-17 zusammen gesetzt. Das gleiche gilt für den zweiten Schlüssel mit Zufallszahl 2 und den dritten Schlüssel auch mit Zufallszahl 2.
    Die beiden Zufallszahlen werden in das Chiffrat eingebaut.
    Es wird noch eine Prüfziffer aus einem MD5-Hash des Ergebnisses gebildet und in das Chiffrat eingebaut. Wenn ein Angebot im TryAndError-Verfahren versuchen sollte, die Auswirkungen auf Manipulationen des Chiffrats zu erforschen, so bekommt er kein Ergebnis zurück, weil die Prüfziffernfolge nicht mehr stimmt.
    Das Ergebnis wird base32-codiert, so dass das Chiffrat nur aus Ziffern und Kleinbuchstaben besteht. Eine weitere base64- oder URL-Codierung ist demnach nicht erforderlich.
    Aus meiner Sicht ist durch die Schlüssel-Länge und die durch Zufallszahlen gesteuerte Vervielfachung der möglichen Schlüssel in Kombination mit der dreistufigen Verschlüsselung ein Knacken der Chiffrate eigentlich unmöglich. Aber vielleicht habe ich ja einen Denkfehler dabei und jemand kann mir helfen, diesen zu finden.
    Im Übrigen stelle ich die Funktion über die GNU-Lizenz für jedermann zur freien Verfügung.

    <?php
    /* PHP function brbcrypt Copyright (C) 2018 Bernhard Blasen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.

    Don't remove this text from source code if you distribute it
    */
    ////////////////////////////////////////////////////////////////////////////////////////
    // Aufruf: «returnstring» = brbcrypt(«key», «value», «"encode"|"decode"»);
    // Achtung!!!!!
    ////////////////////////////////////////////////////////////////////////////////////////
    if ( ! function_exists("base32_encode")) {
    include("base32.php");
    }
    if ( ! function_exists("brbcrypt")) {
    function brbcrypt($key, $text, $direction) {
    $text_sv = $text;
    $l_k = strlen($key);
    if($l_k == 0) { // Ohne Key keine Verschlüsselung!!!
    return $text;
    }
    $key2 = md5($key);
    $key3 = strrev($key);
    $l_t = strlen($text);
    $rettext = "";
    $rettext_u = "";
    $k = 0; // Position im Key
    $k2 = 0; // Position in Key2
    if ($direction != "encode") {
    $text = substr($text,0,3) . base32_decode(substr($text,3,strlen($text)-3));
    $md = substr($text,6,4);
    $text = substr($text,0,6).substr($text,9,$l_t - 9);
    $k = ord(substr($text,4,1)) - 64;
    $k2 = ord(substr($text,5,1)) - 64;
    $text = substr($text,3,1).substr($text,7,$l_t - 9);
    if ($md != substr(md5($text),0,4)) {
    return false;
    }
    $l_t = strlen($text);
    } else {
    $k = mt_rand(1,$l_k);
    while ($k > 23 && $k < 33) {
    $k = $k - mt_rand(10,23);
    }
    if ($k < 1) { $k = $k + mt_rand(1,3); }
    if ($k > 56) { $k = $k - mt_rand(10,40); }
    if ($k > 25 && $k < 34) { $k = $k / 2 ; }
    if ($k2 < 1) { $k2 = $k2 + mt_rand(1,3); }
    if ($k2 > 58) { $k2 = $k2 - mt_rand(8,50); }
    $k2 = mt_rand(1,32);
    while ($k2 > 23) {
    $k2 = $k2 - mt_rand(1,23);
    }
    }
    if ($k > $k2) {
    $k3 = $k2;
    } else {
    $k3 = $k;
    }
    $k_save = $k;
    $k2_save = $k2;
    for($i_text = 0; $i_text < $l_t; $i_text++) {
    if($k > $l_k-1) {$k = 0;} // Wenn ende des keys, dann wieder von vorne
    if($k2 > strlen($key2)) {$k2 = 0;} // Wenn ende des keys, dann wieder von vorne
    if ( $direction == "encode" ) {
    $z=ord(substr($text,$i_text,1))+ord(substr($key,$k,1));
    if ( $z > 255 ) {
    $z=$z-256;
    }
    $z = $z+ord(substr($key2,$k2,1));
    if ( $z > 255 ) {
    $z=$z-256;
    }
    $z = $z+ord(substr($key3,$k3,1));
    if ( $z > 255 ) {
    $z=$z-256;
    }
    } else {
    if ( ord(substr($text,$i_text,1)) < ord(substr($key3,$k3,1)) ) {
    $z = ord(substr($text,$i_text,1)) + 256 - ord(substr($key3,$k3,1));
    } else {
    $z = ord(substr($text,$i_text,1)) - ord(substr($key3,$k3,1));
    }
    if ( $z < ord(substr($key2,$k2,1)) ) {
    $z = $z + 256 - ord(substr($key2,$k2,1));
    } else {
    $z = $z - ord(substr($key2,$k2,1));
    }
    if ( $z < ord(substr($key,$k,1)) ) {
    $z = $z + 256 - ord(substr($key,$k,1));
    } else {
    $z = $z - ord(substr($key,$k,1));
    }
    }
    $rettext.= chr($z); // Verschlüsselung
    $k++;
    $k2++;
    }
    if ($direction == "encode") {
    $md = substr(md5($rettext),0,4);
    $x = substr($rettext,0,1).chr($k_save + 64).chr($k2_save + 64).$md.substr($rettext,1,strlen($rettext) - 1);
    return "bv3" . base32_encode($x);
    } else {
    return $rettext;
    }
    }
    }
    ?>
    Für den Ablauf werden die Funktionen base32_encode und base32_decode verwendet:
    <?php
    /* PHP function base32_encode und base32_decode Copyright (C) 2018 Bernhard Blasen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.

    Don't remove this text from source code if you distribute it
    */
    function base32_encode($data) {
    $chars = '0123456789abcdefghjkmnpqrstvwxyz';
    $mask = 0b11111;

    $dataSize = strlen($data);
    $res = '';
    $remainder = 0;
    $remainderSize = 0;

    for($i = 0; $i < $dataSize; $i++) {
    $b = ord($data[$i]);
    $remainder = ($remainder << 8) | $b;
    $remainderSize += 8;
    while($remainderSize > 4) {
    $remainderSize -= 5;
    $c = $remainder & ($mask << $remainderSize);
    $c >>= $remainderSize;
    $res .= $chars[$c];
    }
    }
    if($remainderSize > 0) {
    $remainder <<= (5 - $remainderSize);
    $c = $remainder & $mask;
    $res .= $chars[$c];
    }

    return $res;
    }

    function base32_decode($data) {
    $map = [
    '0' => 0,
    'O' => 0,
    'o' => 0,
    '1' => 1,
    'I' => 1,
    'i' => 1,
    'L' => 1,
    'l' => 1,
    '2' => 2,
    '3' => 3,
    '4' => 4,
    '5' => 5,
    '6' => 6,
    '7' => 7,
    '8' => 8,
    '9' => 9,
    'A' => 10,
    'a' => 10,
    'B' => 11,
    'b' => 11,
    'C' => 12,
    'c' => 12,
    'D' => 13,
    'd' => 13,
    'E' => 14,
    'e' => 14,
    'F' => 15,
    'f' => 15,
    'G' => 16,
    'g' => 16,
    'H' => 17,
    'h' => 17,
    'J' => 18,
    'j' => 18,
    'K' => 19,
    'k' => 19,
    'M' => 20,
    'm' => 20,
    'N' => 21,
    'n' => 21,
    'P' => 22,
    'p' => 22,
    'Q' => 23,
    'q' => 23,
    'R' => 24,
    'r' => 24,
    'S' => 25,
    's' => 25,
    'T' => 26,
    't' => 26,
    'V' => 27,
    'v' => 27,
    'W' => 28,
    'w' => 28,
    'X' => 29,
    'x' => 29,
    'Y' => 30,
    'y' => 30,
    'Z' => 31,
    'z' => 31,
    ];

    $data = strtolower($data);
    $dataSize = strlen($data);
    $buf = 0;
    $bufSize = 0;
    $res = '';

    for($i = 0; $i < $dataSize; $i++) {
    $c = $data[$i];
    if(!isset($map[$c])) {
    throw new \Exception("Unsupported character $c (0x".bin2hex($c).") at position $i");
    }
    $b = $map[$c];
    $buf = ($buf << 5) | $b;
    $bufSize += 5;
    if($bufSize > 7) {
    $bufSize -= 8;
    $b = ($buf & (0xff << $bufSize)) >> $bufSize;
    $res .= chr($b);
    }
    }

    return $res;
    }
    ?>

  • #2
    Zitat von brb6708 Beitrag anzeigen
    Um Scripts man-in-the-middle-sicher zu machen
    Dafür wurde HTTPS erfunden.

    Kommentar


    • #3
      https schützt leider nicht gegen den man-in-the-middle...

      Kommentar


      • #4
        Hab zwar nur kurz drüber geschaut, aber die base32-Kodierung kannst du dir sparen. Da erkennt man schon am Muster, um was es sich handelt.

        Gruß
        Peter
        Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
        Meine Seite

        Kommentar


        • #5
          Zitat von brb6708 Beitrag anzeigen
          https schützt leider nicht gegen den man-in-the-middle...
          Doch.

          Kommentar


          • #6
            Zitat von h3ll Beitrag anzeigen
            Doch.
            Nicht unbedingt. Ist zwar ein alter Artikel, aber wer weiß.

            Gruß
            Peter
            Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
            Meine Seite

            Kommentar


            • #7
              https schützt nur den Traffic, der zwischen den beiden Endpunkten läuft. Wenn Du aber über einen manipulierten Namensserver einen Zwischenhost einbaust, dann liefert der das Zertifikat, bekommt dann den Request und kann damit machen, was er will (z. B. den Request an den wirklich gewünschten Server weiterleiten, dessen Antworten wieder an den Requester zurücksenden. Dabei hat er vollen Zugriff auf die Inhalte!
              Nachdem ein Angreifer ein Zertifikat bereits für nen Appel und'n Ei kaufen kann, wäre es notwendig, immer den Inhalt des Zertifikats abzuprüfen. Das würde das Ganze System aber ziemlich pflegeaufwändig machen.
              Zuletzt geändert von brb6708; 30.08.2017, 16:02.

              Kommentar


              • #8
                Die Base32-Codierung ist nur dafür da, dass sicher gestellt ist, dass nur Ziffern und Buchstaben im Chiffrat vorhanden sind. Auf die Verschlüsselung hat das keinen Einfluss.
                Aufgrund der dreistufigen Verschlüsselung, die über Zufallszahlen variiert wird, ergeben sich keinerlei Muster, die in irgend einer Weise ausgewertet werden könnten. Es gibt einfach viel zu viele Key-Kombinationen, die dafür sorgen, dass keine Muster entstehen.

                Kommentar


                • #9
                  Zitat von brb6708 Beitrag anzeigen
                  https schützt nur den Traffic, der zwischen den beiden Endpunkten läuft. Wenn Du aber über einen manipulierten Namensserver einen Zwischenhost einbaust, dann liefert der das Zertifikat, bekommt dann den Request und kann damit machen, was er will (z. B. den Request an den wirklich gewünschten Server weiterleiten, dessen Antworten wieder an den Requester zurücksenden. Dabei hat er vollen Zugriff auf die Inhalte!
                  Der kann den Request aber nicht entschlüsseln.

                  Zitat von brb6708 Beitrag anzeigen
                  Nachdem ein Angreifer ein Zertifikat bereits für nen Appel und'n Ei kaufen kann, wäre es notwendig, immer den Inhalt des Zertifikats abzuprüfen. Das würde das Ganze System aber ziemlich pflegeaufwändig machen.
                  Was auch immer dir vorschwebt, ist PHP sowieso das falsche Werkzeug. Wenn dann sollte der Datenstrom allgemein verschlüsselt werden und nicht nur einzelne POST-Werte.

                  Warum sollten GET-Werte nicht verschlüsselt werden? Und was ist mit PUT, DELETE, usw.? Oder Dateiuploads auch unverschlüsselt? Wie siehts mit Websocket-Verbindungen aus?

                  Wie auch immer, du versuchst das Problem (ob es jetzt real vorhanden ist oder nicht) nur in einem sehr sehr eingeschränkten Bereich zu behandeln mit einem Werkzeug, das dafür eigentlich gar nicht zuständig sein sollte. Für mich klingt das irgerndwie nach Zeitverschwendung und Beschäftigungstherapie.

                  Mal davon abgesehen gibt es bereits zahlreiche fertige und vielfach geprüfte Verschlüsselungsverfahren. Inwiefern sollte deines jetzt seriöser/zuverlässiger sein? Gerade bei Verschlüsselungsverfahren ist es so, dass diese Eigenbastellösungen meistens die anfälligsten sind.
                  Zuletzt geändert von h3ll; 30.08.2017, 16:35.

                  Kommentar


                  • #10
                    Zitat von h3ll Beitrag anzeigen
                    Der kann den Request aber nicht entschlüsseln.
                    kann er doch - er gibt sich ja als der aus, den der Requester erreichen möchte und er hat auch noch ein gültiges Zertifikat. Die einzige Möglichkeit ist es, im Script die Zertifikatsdaten einzulesen und zu prüfen. Das bedeutet aber bei jeder Zertifikatsänderung eine Anpassung entwerder der Scripts oder der Datenbank.

                    Zitat von h3ll Beitrag anzeigen
                    ...mit einem Werkzeug, das dafür eigentlich gar nicht zuständig sein sollte. Für mich klingt das irgerndwie nach Zeitverschwendung und Beschäftigungstherapie.

                    Mal davon abgesehen gibt es bereits zahlreiche fertige und vielfach geprüfte Verschlüsselungsverfahren. Inwiefern sollte deines jetzt seriöser/zuverlässiger sein? Gerade bei Verschlüsselungsverfahren ist es so, dass diese Eigenbastellösungen meistens die anfälligsten sind.
                    Das Problem ist, dass die "fertigen Lösungen" (z.B. openssl_encode/openssl_decode) wesentlich weniger performant sind und in den meisten Fällen auch noch längere Chiffrate erzeugen. Es kommt nicht darauf an, ob es POST- GET- SOAP- oder was auch immer für Daten sind. Es kommt darauf an, dass ich eine hinreichend sichere Funktion habe, die mir Begriffe verschlüsselt und entschlüsselt, die ich z.B. mit Ajax dynamisch in Webseiten einbringen kann. Aber darum geht's bei meiner Frage nicht. Ich suche die Schwachpunkte meiner Lösung. Und ich möchte eben herausfinden, ob mein Verfahren "seriös" oder "Bastelstube" ist - und das möglichst begründet. Sorry für die Hartnäckigkeit

                    Kommentar


                    • #11
                      Ich würde sowas jedenfalls niemals einsetzen, weil viel zu umständlich und mühsam. In einer PHP-Anwendung will ich mich um Dinge, die Angelegenheit einer anderen Schicht sind, nicht kümmern müssen. Genauso wie ich in meiner PHP-Anwendung nicht HTTPS-Abfagen "per Hand" verschlüssele, sondern das dem System überlasse.

                      Kommentar

                      Lädt...
                      X