IT Sicherheit

Verschlüsselung und Entschlüsselung mit OpenSSL

Lesezeit ca. 4 Min.

Seit PHP 7.2 ist Verschlüsselung und Entschlüsselung mit OpenSSL die empfohlene und sicherste Methode. Dieser Artikel zeigt, wie durch die PHP Erweiterung die OpenSSL-Bibliothek in PHP Programmen genutzt werden kann.

Es ist wahrscheinlich nur wenigen PHP Entwicklern bewusst gewesen, dass die bisher verwendete Bibliothek zum Ver- und Entschlüsseln mcrypt, alles andere als sicher gewesen ist. Eines der größten Probleme – aus der Sicht von Sicherheitserfordernissen – ist, dass die mcrypt Erweiterung fortgeschrittene Kenntnisse über Kryptographie erfordert, um sie erfolgreich einzusetzen, was nur sehr wenige PHP Entwickler haben. Dies führte zu einem falschen Gebrauch und letztlich zu Problemen in Bezug auf Datensicherheit. Das nächste Problem mit der mcrypt Bibliothek ist die Tatsache, dass sie seit 2007 nicht mehr weiterentwickelt wurde und somit seitdem keine Fehler mehr beseitigt wurden und keine Weiterentwicklung stattgefunden hat. Daher ist es wichtig zu verstehen, wie man unter PHP eine starkte Ver-/entschlüsselung auch ohne den Einsatz von mcrypt realisieren kann.

Die Lösung des zuvor genannten Problems ist der Einsatz der OpenSSL Bibliothek. Diese PHP Erweiterung wird aktiv weiterentwickelt und verfügt über moderne und sehr starke Ver- und Entschlüsselungsmethoden.

Für die Nutzung der OpenSSL Erweiterung muss der entsprechende Eintrag in der php.ini entkommentiert sein / werden!

Zunächst müssen sie prüfen, welche Verschlüsselungsmethoden in Ihrer Installation vorhanden sind, um die weitere Vorgehensweise bei der Programmierung zu bestimmen. Zu diesem Zweck schreiben Sie bitte ein kleines Testskript, mit welchem Sie die Cipher-Methoden herausfinden können:

<?php
$ciphers = openssl_get_cipher_methods();
echo implode(',', $ciphers);
?>

Das Ergebnis sollte in etwa so aussehen, wie auf dem folgenden Bild:

Cipher-Methoden

Sie sehen, dass die vorhandenen Verschlüsselungsmethoden auf den Algorithmen

  • Advanced Encryption Standard (AES)
  • BlowFish (BF)
  • CAMELLIA
  • CAST5
  • Data Encryption Standard (DES)
  • Rivest Cipher (RC)
  • SEED

basieren. Die aufgeführten Methoden sind einmal groß- und einmal kleingeschrieben.

Als nächstes müssen Sie bestimmen, welche Methode für Ihre Zwecke am besten geeignet ist. Hierzu eine Übersicht in der folgenden Tabelle:

MethodeVeröffentlichtSchlüsselgröße (bit)Blockgröße (byte)
camellia2000128,192,25616
aes1998128,192,25616
seed199812816
cast5199640 - 4488
bf19931 - 10248
rc219878 - 10248
des197756 (+8 Paritätsbits)8

Als nächstes müssen Sie bestimmen, in welchem Operationsmodus die Blockverschlüsselung arbeiten soll. Die üblichen Möglichkeiten hierzu entnehmen Sie bitte der folgenden Tabelle:

ModusBedeutung
ECBElectronic Code Block
CBCCipher Block Chaining
CFBCipher Feedback
OFBOutput Feedback
CTRCounter
CCMCounter with CBC-MAC
GCMGalois/Counter Mode
XTSXEX-based Tweaked-codebook mode with ciphertext Stealing

Ich werde nun in einem Beispiel einen Text mit der AES Verschlüsselungsmethode, einem 256-bit Schlüssel im XTS Modus verschlüsseln. Dazu verwende ich die PHP Funktion openssl_encrypt(). Die erforderlichen Parameter entnehmen Sie bitte der folgenden Tabelle:

ParameterBeschreibung
dataDie zu verschlüsselnde Zeichenkette.
methodVerschlüsselungsmethode
keyDer Schlüssel
optionsEine Bitmaske aus OPENSSL_RAW_DATA und OPENSSL_ZERO_PADDING.
ivInitialisierungsvektor (darf nicht NULL sein).

Der entsprechende PHP Code hierzu sieht so aus:

$cleartext = "Dies ist ein unverschlüsselter Text.";
$cipher = 'AES-256-XTS';
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$key = random_bytes(16);
$ciphertext_raw = openssl_encrypt($cleartext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
$ciphertext = base64_encode($ciphertext_raw);

Für den Schlüssel habe ich die Funktion random_bytes() mit einem Wert von 16 genommen (dies ist ein Erfahrungswert und kann je nach Länge des zu verschlüsselnden Textes und der Verschlüsselungsmethode gelegentlich variieren). Ich hätte in diesem Fall auch $ivlen als Parameter nehmen können. Im Ergebnis wäre es der gleiche Wert gewesen. Die verschlüsselte Zeichenkette habe ich noch mit BASE-64 kodiert, um sie für die Weiterverarbeitung bzw. Speicherung in einer Datenbank handlicher zu machen. Je nach Anwendungsfall ist dies natürlich nicht erforderlich.

Möchte man sich die jeweiligen Resultate des Verschlüsselungsvorgangs im Detail ansehen, so dienen dazu die folgenden Zeilen:

echo "$cleartext";
echo "$cipher";
echo "$key";
echo "$ivlen";
echo "$iv";
echo "$ciphertext_raw";
echo "$ciphertext";

So können Sie jeden einzelnen Schritt genau nachvollziehen.

Zum Entschlüsseln benötige ich nun den gleichen Schlüssel und Initialisierungsvektor und darf nicht vergessen, vorher den BASE-64 Wert zu dekodieren:

$clearedtext = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv);

Zur Kontrolle kann man sich nun mit einem echo oder print Befehl die entschlüsselte Zeichenkette ausgeben lassen.

Die Ausgabe des gesamten Vorgangs können sie in im folgenden Bild sehen:

Verschlüsselungsprozess

Ähnliche Artikel:

Kommentare(6)

Karsten EsserApr 2020

Hier ist der entsprechende Sourcecode:

$passwort = “Test”;
$text_zusatz = “Das_sind-Mind_16!Zeichen”;

$cleartext = $passwort.$text_zusatz;
$cipher = ‘AES-256-XTS’;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$key = random_bytes(16);
$ciphertext_raw = openssl_encrypt($cleartext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
$ciphertext = base64_encode($ciphertext_raw);

echo “$cleartext”;
echo “$cipher”;
echo “$key”;
echo “$ivlen”;
echo “$iv”;
echo “$ciphertext_raw”;
echo “$ciphertext”;

$clearedtext = openssl_decrypt(base64_decode($ciphertext), $cipher, $key, OPENSSL_RAW_DATA, $iv);
echo $clearedtext.”;
$passwort_clear = explode($text_zusatz, $clearedtext);
echo $passwort_clear[0].”;

/////////////////////////////////////////

$passwort_in_variable = “wes1XrwpuwGrN4IERriuCcMsNIIB0DDbgiGcKw==”;

$clearedtext = openssl_decrypt(base64_decode($passwort_in_variable), $cipher, $key, OPENSSL_RAW_DATA, $iv);
echo $clearedtext.”;
$passwort_clear = explode($text_zusatz, $clearedtext);
echo $passwort_clear[0];

    adminApr 2020

    Hallo Karsten,

    Du solltest einen reinen Texteditor zum Programmieren verwenden und nicht Word oder eine andere Textverarbeitung.
    Das Problem in Deinem Sourcecode sind die Anführungsstriche, sowohl die einfachen, als auch die doppelten.
    Ich hatte den Source bei mir getestet und bekam Fehlermeldungen, die erst dadurch behoben wurden, dass ich die Anführungszeichen neu setzte. Danach lief alles korrekt. Unten fehlt bei einem Echo noch das öffnende Anführungszeichen.

KarstenApr 2020

Guten Tag,
ich finde die Lösung super und wollte diese auch umsetzen. Das hin und her verschlüsseln funktioniert.
Wenn ich jedoch den verschlüsselten Code abspeicher (Sei es in einer Datenbank oder in einer Variable als String), dann kann ich diesen Code nicht mehr Entschlüsseln.
Was mache ich hier falsch? Wieso funktioniert dies nicht?

    adminApr 2020

    In dem Beispiel wurde der verschlüsselte Text in eine Variable gespeichert und aus dieser wieder entschlüsselt. Genauso wird es auch gemacht, wenn man den verschlüsselten Text aus der Datenbank nimmt. Dann wird er doch auch erst einmal in eine Variable gespeichert und für die Entschlüsselung müssen dieselben Schritte vollzogen werden, wie bei der Verschlüsselung.
    Wenn es bei Ihnen nicht klappt, dann posten Sie mir doch bitte Ihren Sourcecode hier in den Kommentarbereich. Dann kann ich evtl. erkennen, woran es hapert.

JürgenJan 2020

“Als nächstes müssen Sie bestimmen, welche Methode für Ihre Zwecke am besten geeignet ist. Hierzu eine Übersicht in der folgenden Tabelle:”

Für mich ist eigentlich nur interessant wie ich das bestimmen kann. Ich will Daten abrufen und diese sollen entsprechend “sicher” verschlüsselt sein.

    adminJan 2020

    Aus diesem Grund habe ich weiter unten ein Beispiel gebracht, dass Sie gerne für Ihre eigenen Zwecke so übernehmen können. Die weiteren Alternativen habe ich der Vollständigkeit halber mit aufgeführt, weil es eben viele verschiedene Möglichkeiten der Verschlüsselung gibt. Es gibt weder nur einen Weg, noch den “besten” Weg. Es hängt immer davon ab, was man mit der Verschlüsselung erreichen will. Alle Methoden im Detail zu erläutern, hätte den Rahmen dieses Artikels gesprengt. Dazu gibt es ganze Bücher voll mit Informationen zu Verschlüsselungstechniken. Dieser Artikel stellt lediglich eine Übersicht dar, wie man unter PHP Daten verschlüsseln kann, welche Verschlüsselungsmethoden es gibt und mit einem Beispiel, wie man konkret so eine Verschlüsselung realisieren kann.

Fragen oder Feedback zu diesem Artikel

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert