Forum: PC-Programmierung Verschlüsseln in PHP


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Kolja L. (kolja82)


Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

ich habe ein PHP Script geschrieben, welches aus den Logindaten eine 
verschlüsselte JSON Date erstellt und wollt emal fragen, ob ich es 
grundsätzlich richtig (oder zumindest nicht gänzlich falsch) mache:


User-Login:
1
if (isset($_POST['u_name']) 
2
       && $_POST['u_name'] != '' 
3
 && isset($_POST['u_password']) 
4
       && $_POST['u_password']) != ''{
5
    $_SESSION['user_ID']   = md5($_POST['u_name'] . $_POST['u_password']);
6
    $_SESSION['user_PW']   = md5($_POST['u_password']);
7
}

Nach dem Login gibt es also eine ID und ein Passwort in der Session, mit 
denen dann die Datei aufgerufen und entschlüsslt wird.

Der Aufruf der secure() Funktion:
1
$db_file = $dir_db . '/' . $user_ID;
2
// load
3
$data = secure('decrypt', $_SESSION['user_PW'], $db_file, '');
4
// save
5
secure('encrypt', $_SESSION['user_PW'], $db_file, $data);


Die secure() Funktion selbst:
1
function secure($action, $key, $file, $string){
2
    $output = false;
3
    $method = 'AES-256-CBC';
4
    $init_vector = 'just some ramdom text';
5
    $key = hash('sha256', $key);
6
    $init_vector = substr(hash('sha256', $init_vector), 0, 16);
7
8
    if ('encrypt' == $action) {
9
        $string = json_encode($string);
10
        $string = openssl_encrypt($string, $method, $key, 0, $init_vector);
11
        $string = base64_encode($string);
12
        if (file_put_contents($file, $string) > 0) {
13
            $output = true;
14
        }
15
    } elseif ('decrypt' == $action) {
16
        $string = file_get_contents($file);
17
        $string = base64_decode($string);
18
        $string = openssl_decrypt($string, $method, $key, 0, $init_vector);
19
        $output = json_decode($string, true);
20
        if (is_string($output)) {
21
            $output = json_decode($output, true);
22
        }
23
    }
24
    return $output;
25
}


Der gezeigte Code ist nur ein Teil des Skriptes, welches ich auf Github 
habe: https://github.com/KoljaL/SecureServices


Gruß Kolja

von Lukas T. (tapy)


Bewertung
1 lesenswert
nicht lesenswert
Generell sollte zumindest bei der Session noch ein nur für diese Session 
gültiger Salt-String mit rein, um erstens das Passwort nicht ganz so 
leichtfertig preis zu geben und zweitens wenigstens etwas gehen 
Replay-Attacken zu tun.

Das ist natürlich schlecht für deinen Ansatz, der die ID aus Namen und 
Passwort generiert, aber da bin ich mir auch ziemlich sicher, dass ich 
das nicht so machen würde.

Das ist natürlich nur meine Meinung und kein "guter Rat", denn sowas ist 
ein heißes Thema. Es kommt immer darauf an, gegen wen Du die Daten 
schützen möchtest.

von Εrnst B. (ernst)


Bewertung
1 lesenswert
nicht lesenswert
Kolja L. schrieb:
    $key = hash('sha256', $key);
    $init_vector = substr(hash('sha256', $init_vector), 0, 16);


du erzeugst den Key (und IV) als hash ohne "raw_output=true". Damit wird 
das Ergebnis als Hexadezimal-Ziffern 0-9a-f kodiert, also sind pro Byte 
im Key nur max. 4 Bit Passwort-Abhängig. ("maximal", weil evtl. vorher 
das MD5 noch was wegnimmt...)

Damit schwächst du die Verschlüsselung extrem, sie ist dadurch 
mindestens um den Faktor
340282366920938463463374607431768211456 schneller zu knacken. Das kann 
den Unterschied zwischen "Nachmittag mit der Grafikkarte" und "Nach dem 
Ende des Universums Gott um neuen Urknall bitten" machen.


Für die Anwendung Passwort -> Encryption-Key gibt's übrigens extra den 
PBKDF2-Algorithmus, bei dem sich Leute mit mehr Ahnung Gedanken gemacht 
haben.
https://de.wikipedia.org/wiki/PBKDF2
https://www.php.net/manual/de/function.hash-pbkdf2.php

Wär schonmal um welten besser als dein einstufiges SHA. Wenn du noch 
Angst vor ASIC-Minern hast, dann evtl. Scrypt. Das verwenden manche 
Crypto-Währungen (Litecoin z.B), um das Minen auf ASIC/FPGA zu 
erschweren.

: Bearbeitet durch User
von Kolja L. (kolja82)


Bewertung
0 lesenswert
nicht lesenswert
Lukas T. schrieb:
> Generell sollte zumindest bei der Session noch ein nur für diese Session
> gültiger Salt-String mit rein, um erstens das Passwort nicht ganz so
> leichtfertig preis zu geben und zweitens wenigstens etwas gehen
> Replay-Attacken zu tun.

Im ersten Ansatz war in dem Passworthash auch noch der Timestamp des 
Logins enthalten, das hielt ich für ne gute Idee und es funktioniert ja 
auch, zumindest bis zum nächsten Login...

Lukas T. schrieb:
> Das ist natürlich nur meine Meinung und kein "guter Rat", denn sowas ist
> ein heißes Thema. Es kommt immer darauf an, gegen wen Du die Daten
> schützen möchtest.

Danke und wie gesagt, den Ansatz "SessionSalt" kann ich nachvollziehen. 
Für mich ist das Script als privater Link- und Passwortmanager gedacht 
und da ich nicht reich&berühmt bin, müsste ich mich von jedem Angrif 
wohl geehrt fühlen.

Εrnst B. schrieb:
> du erzeugst den Key (und IV) als hash ohne "raw_output=true".

Danke, genau solche Hinweise sind für mich wichtig.


Εrnst B. schrieb:
> Für die Anwendung Passwort -> Encryption-Key gibt's übrigens extra den
> PBKDF2-Algorithmus,

Du meinst an den Stellen:
1
$key = hash('sha256', $key);
2
$init_vector = substr(hash('sha256', $init_vector), 0, 16);
besser so:
1
$key = hash_pbkdf2('sha256', $key, $salt, $iterations, 20, true);
2
$init_vector = hash_pbkdf2('sha256', $init_vector , $salt, $iterations, 16, true);
?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.