Inhaltsverzeichnis
einzelne Dateien mit openSSL verschlüsseln
Die Stärke der Sicherheit der drei besten Cipher/Verschlüsselungsarten ist wie folgt, der sicherste steht oben:
- serpent (der sicherste in
CryptSetup- ganzes Dateisystem verschlüsseln) - twofish (der sicherste in
GPG- einzelne Dateie verschlüsseln) → GPG-Verschlüsselung mit Passwort - blowfish (der sicherste in
openSSL- einzelne Dateie und Zeichenketten verschlüsseln) → OpenSSL-Verschlüsselung mit Passwort → OpenSSL-Verschlüsselung von Zeichenketten
Leider musste ich Anfang des Jahres 2024 (mit FreeBSD 14.0) feststellen, dass OpenSSL die hier genannten Beispiele mit BlowFish (bf-cbc) nicht mehr ausführt. Um diese Kommandos weiterhin ausführen zu können, muß man stattdessen den schwächeren AES (aes-256-cbc) verwenden.
Alle Cipher, die von dem Kommando openssl list -cipher-commands ausgegeben werden, können für die hier genannten Beispiel verwendet werden.
Bei symetrischer Verschlüsselung (z.B. nur mit Passwort), sollte immer die Option -salt verwendet werden!
Symetrische Verschlüsselung (mit Passwort)
Zeichenkette symetrisch verschlüsseln
eine Datei mit geheimem Inhalt anlegen:
> touch geheim.txt > chmod 0600 geheim.txt > echo "Das ist ein geheimer Text" > geheim.txt
den geheimen Dateiinhalt verschlüsseln:
> cat geheim.txt | openssl enc -salt -iter 1234567 -aes-256-cbc -a -e > geheim.ssl enter bf-cbc encryption password: Verifying - enter bf-cbc encryption password: > rm -f geheim.txt > cat geheim.ssl U2FsdGVkX19JcdCWBa4sGZAkeDeFrsRlWnvl85lBQ+LXTToAwJLFuiF458LkLS7t
das Geheimnis wieder sichtbar machen:
> cat geheim.ssl | openssl enc -salt -iter 1234567 -aes-256-cbc -a -d enter bf-cbc decryption password: Das ist ein geheimer Text
Dateien symetrisch verschlüsseln
Datei mit OpenSSL auf der CLI verschlüsseln
Datei verschlüsseln (AES):
> echo "ganz geheimer Text" > datei.txt > openssl enc -a -salt -iter 1234567 -aes-256-cbc -e -in datei.txt -out datei.aes oder > openssl enc -a -salt -iter 1234567 -aes-256-cbc -e -in datei.txt > datei.aes
Datei wieder entschlüsseln (AES):
> openssl enc -a -salt -iter 1234567 -aes-256-cbc -d -in datei.aes -out datei2.txt oder > cat datei.aes | openssl enc -a -salt -iter 1234567 -aes-256-cbc -d > datei2.txt
einen ganzen Verzeichnisbaum verschlüsseln (AES):
> tar -cf - /Verzeichnis | openssl enc -salt -iter 1234567 -aes-256-cbc -e -out verzeichnis.tar.aes oder > tar -cf - /Verzeichnis | openssl enc -salt -iter 1234567 -aes-256-cbc -e > verzeichnis.tar.aes
und wieder entschlüsseln (AES):
> openssl enc -salt -iter 1234567 -aes-256-cbc -d -in verzeichnis.tar.aes | tar -x -f - oder > cat verzeichnis.tar.aes | openssl enc -salt -iter 1234567 -aes-256-cbc -d | tar -x -f -
Datei verschlüsseln (mit BF und ohne Passwrtabfrage):
> openssl enc -a -salt -iter 1234567 -bf-cbc -md sha512 -k "geheimes Passwort" -e -in datei.txt -out datei.ssl enter bf-cbc encryption password: Verifying - enter bf-cbc encryption password:
Datei verschlüsseln (mit BF und ohne Passwrtabfrage):
> openssl enc -a -salt -iter 1234567 -bf-cbc -md sha512 -k "geheimes Passwort" -d -in datei.ssl oder > cat datei.ssl | openssl enc -a -salt -iter 1234567 -bf-cbc -md sha512 -k "geheimes Passwort" -d
Datei mit OpenSSL per Skript verschlüsseln
Die Datei /tmp/datei verschlüsseln (lesbare Textdatei erzeugen):
~/bin/Datei_verschluesseln.sh -w 1234567 -m bf -t -d /tmp/datei enter bf-cbc encryption password: Verifying - enter bf-cbc encryption password: -rw-r--r-- 1 fritz wheel 33B 4 Okt. 17:43 /tmp/datei.ssl
Die Datei /tmp/datei.ssl (lesbare Textdatei) entschlüsseln:
~/bin/Datei_verschluesseln.sh -w 1234567 -m bf -t -d /tmp/datei.ssl enter bf-cbc decryption password: -rw-r--r-- 1 fritz wheel 6B 4 Okt. 17:43 /tmp/datei
- ~/bin/Datei_verschluesseln.sh
#!/usr/bin/env bash #------------------------------------------------------------------------------# # # Dieses Skript erstellt eine verschlüsselte Kopie einer Datei. # # openssl enc -a -salt -iter 1234567 -bf-cbc -e # openssl enc -a -salt -iter 1234567 -bf-cbc -d # #------------------------------------------------------------------------------# #VERSION="v2020100400" # erste Version VERSION="v2020101000" # es kann jetzt auch ein Zielverzeichnis angegeben werden AVERZ="$(dirname ${0})" # Arbeitsverzeichnis, hier liegen diese Dateien #==============================================================================# if [ "x${1}" = x ] ; then ${0} -h exit 10 fi while [ "${#}" -ne "0" ]; do case "${1}" in -w) WIEDERHOLUNGEN="${2}" # es sollten mehr als 1 Mio. mal wiederholt werden shift ;; -m) METHODE="-${2}" # BlowFish als Ersatz für Serpent shift ;; -t) ASCII="-a" # nicht in der platzsparenden Binärform, sondern in Text-Form shift ;; -d) DATEI="${2}" # Dateiname shift ;; -z) ZIEL="${2}" # Zielverzeichnis shift ;; -p) PASSWORT="-pass pass:${2}" # Passwort shift ;; -h) # ausgabe_hilfe echo "HILFE: # die Reihenfolge der Optionen ist unwichtig # Anzahl der Wiederholungen, es sollten mehr als 1 Mio. sein -w 1234567 # Verschlüsselungsmethode, da OpenSSL kein Serpent kann, empfehle ich BlowFish -m bf # nicht in Binärform, sondern in Textform # wenn diese Option nicht angegeben wird, dann wird eine platzsparende Datei mit Binärinhalt erzeugt -t # Datei mit zu verschlüsselndem Inhalt -d geheim.txt # Datei mit zu entschlüsselndem Inhalt -d geheim.txt.ssl # allgemeine Form ${0} -w [Wiederholungen] -m [Verschlüsselungsmethode] [in Binärform oder Textform] -d [verschlüsseln oder entschlüsseln] # verschlüsseln einer Datei, in der platzsparenden Binärform ${0} -w 1234567 -m bf -d geheim.txt # entschlüsseln einer Datei ${0} -w 1234567 -m bf -d geheim.txt.ssl # verschlüsseln einer Datei, in sichtbarer Textform (-t) # das ist geeignet für E-Mails oder zum abschreiben ${0} -w 1234567 -m bf -t -d geheim.txt # entschlüsseln einer Datei, die in Textform (ASCII) vorliegt (-t) ${0} -w 1234567 -m bf -t -d geheim.txt.ssl # das Passwort kann auch (für automatische Abarbeitungen) direkt übergeben werden ${0} -w 1234567 -m bf -d geheim.txt -p 'geheimes Passwort' " exit 20 ;; *) if [ "$(echo "${1}"|egrep '^-')" ] ; then echo "Der Parameter '${1}' wird nicht unterstützt!" export STOP="Ja" fi shift ;; esac done #==============================================================================# ### Kontrolle if [ -e "${DATEI}" ] ; then ls -lha ${DATEI} else echo "Es konnte die Datei '${DATEI}' nicht gefunden werden. Abbruch!" exit 30 fi if [ "x${WIEDERHOLUNGEN}" = x ] ; then WIEDERHOLUNGEN="4567890" fi if [ "x${METHODE}" = x ] ; then METHODE="bf" fi V_NAME="$(dirname "${DATEI}")" if [ "x${ZIEL}" = x ] ; then ABS="$(echo "${DATEI}" | egrep '^[/]')" if [ "x${ABS}" = x ] ; then ZIEL="." fi fi #==============================================================================# ### Programm PROGRAMM="$(which openssl)" if [ "x${PROGRAMM}" = "x" ] ; then echo "Es konnte das Programm 'openssl' nicht gefunden werden. Abbruch!" exit 40 fi #==============================================================================# ENDUNG="$(echo "${DATEI}" | rev | awk '{sub("[.]"," "); print tolower($1)}' | rev)" #echo "ENDUNG='${ENDUNG}'" if [ "${ENDUNG}" = "ssl" ] ; then D_NAME="$(basename "${DATEI}" | rev | awk '{sub("[.]"," "); print $2}' | rev)" echo "#=> ${ZIEL}/${V_NAME}/${D_NAME}" if [ -e "${ZIEL}/${V_NAME}/${D_NAME}" ] ; then echo "Die Datei mit dem Namen '${D_NAME}' existiert schon." else mkdir -p "${ZIEL}/${V_NAME}/" touch "${ZIEL}/${V_NAME}/${D_NAME}" chmod 0600 "${ZIEL}/${V_NAME}/${D_NAME}" cat ${DATEI} | openssl enc -salt -iter ${WIEDERHOLUNGEN} ${METHODE} ${ASCII} ${PASSWORT} -d > "${ZIEL}/${V_NAME}/${D_NAME}" ls -lha "${ZIEL}/${V_NAME}/${D_NAME}" fi else echo "#=> ${ZIEL}/${V_NAME}/${DATEI}".ssl if [ -e "${ZIEL}/${V_NAME}/${DATEI}.ssl" ] ; then echo "Die Datei mit dem Namen '${DATEI}.ssl' existiert schon." else mkdir -p "${ZIEL}/${V_NAME}/" touch "${ZIEL}/${V_NAME}/${DATEI}".ssl chmod 0600 "${ZIEL}/${V_NAME}/${DATEI}".ssl cat ${DATEI} | openssl enc -salt -iter ${WIEDERHOLUNGEN} ${METHODE} ${ASCII} ${PASSWORT} -e > "${ZIEL}/${V_NAME}/${DATEI}".ssl ls -lha "${ZIEL}/${V_NAME}/${DATEI}".ssl fi fi
Asymetrische Verschlüsselung (mit SSL-Schlüssel)
mit RSA-Schlüssel
Große Dateien können nicht asymetrisch verschlüsselt werden! ⇒ How to encrypt a large file in openssl using public key
Die übliche Vorgehensweise, für das verschlüsseln von langen Dateien sieht wie folgt aus: Große Dateien werden jedes Mal mit einem neuen zufällig generierten, symmetrischen Schlüssel Verschlüsselt. Der dazu verwendete symmetrische Schlüssel wird mit dem öffentlichen RSA-Schlüssel verschlüsselt. Dann wird der Chiffre-Text zusammen mit dem verschlüsselten symmetrischen Schlüssel an den Empfänger übertragen. Der Empfänger entschlüsselt den symmetrischen Schlüssel mit seinem privaten Schlüssel und verwendet dann den symmetrischen Schlüssel zum Entschlüsseln der Nachricht (Chiffre-Text).
Datei verschlüsseln:
> echo "ganz geheimer Text" > datei.txt > openssl pkeyutl -encrypt -inkey cert.pem -certin -in datei.txt -out datei.ssl oder > openssl pkeyutl -encrypt -inkey public.pem -pubin -in datei.txt -out datei.ssl
Datei entschlüsseln:
> openssl pkeyutl -decrypt -inkey private.pem -in datei.ssl -out datei.txt
Manchmal gibt es Probleme (meist beim entschlüsseln), wenn bestimmte Zeichen in der Datei vorkommen. In soeinem Fall ist es hilfreich, die zu verschlüsselnden Dateien vorher in Base64-Kode umzuwandeln.
> base64 Datei.txt > Datei.txt.b64 > openssl pkeyutl -encrypt -pubin -inkey public-ssl-key.pem -in Datei.txt.b64 -out Datei.txt.b64.ssl > openssl pkeyutl -decrypt -inkey privat-ssl-key.pem -in Datei.txt.b64.ssl -out Datei.txt.b64.txt
S/MIME-Verschlüsselung (E-Mail-Format)
jetzt schreiben wir einen kurzen Text, an dem wir die Verschlüsselung+Entschlüsselung ausprobieren:
> echo "Text" > message_klartext.txt
eine Zeichenkette mit einem Zertifikat verschlüsseln:
> openssl smime -encrypt -aes256 -in datei.txt -out datei.ssl cert.pem
die verschlüsselte Zeichenkette mit dem privaten Schlüssel entschlüsseln:
> openssl smime -decrypt -inkey private.pem -in datei.ssl -out datei.txt > cat datei.txt Text
mit PHP
verschlüsseln
- php_openssl_verschl.php
<?php // // verschl. // // ${0} [Datei mit oeffentl. Schluessel] Text // #${0} [Datei mit oeffentl. Schluessel] [Datei mit Text] // // 1. Datei mit oeffentl. Schluessel einlesen $pkey=trim(file_get_contents($argv[1])); // Text aus dem 2. Parameter einlesen $klartext=trim($argv[2]); // Text aus der 2. Datei einlesen //$klartext=trim(file_get_contents($argv[2])); // Verschluesselungsfunktion function opensslPublicEncrypt($key_resource, $source) { openssl_public_encrypt($source, $crypttext, $key_resource); return(base64_encode($crypttext)); } // Text verschluesseln $b64crypt = opensslPublicEncrypt($klartext); // wenn die erzeugte Zeichenfolge am Ende mehr als ein '=' enthaelt, // dann ist sie nicht wieder zu entschluesseln // und muss deshalb erneut verschluesselt werden $search = "=="; while(stripos(strrev($b64crypt), strrev($search)) != 0) { $b64crypt = opensslPublicEncrypt($klartext); } $verschl = trim($b64crypt); echo "$verschl\n"; // nur ein Beispiel // $DATEI="/var/www/vkey.txt"; //$dateihandle = fopen("$DATEI","w"); //fwrite($dateihandle, $b64crypt); ?>
> php php_openssl_verschl.php PUBLIC_KEY.pem geheim03 > verschluesselter_text.txt
entschlüsseln
- php_openssl_entschl.php
<?php // // entschl. Text // // ${0} [Datei mit privatem Schluessel] [Datei mit verschl. Text] // ${0} [Datei mit privatem Schluessel] "verschl. Text" // // liest den verschl. ASCII-Text aus der 2. Datei ein $crypttext=base64_decode(trim(file_get_contents($argv[2]))); // liest den verschl. Text aus dem 2. Parameter ein //$crypttext=base64_decode(trim($argv[2])); // entschl. den Text openssl_private_decrypt($crypttext, $klartext, trim(file_get_contents($argv[1]))); // gibt den Klartext aus echo "$klartext"; ?>
> bash php_openssl_entschl.php PRIVATE_KEY.txt verschluesselter_text.txt geheim03
per Web-Server/Web-Browser
mit PHP
<?php #==============================================================================# ### ### Quelle: ### http://php.net/manual/de/book.openssl.php ### if (isset($_SERVER['HTTPS']) ) { echo "SECURE: This page is being accessed through a secure connection.<br><br>"; } else { echo "UNSECURE: This page is being access through an unsecure connection.<br><br>"; } #==============================================================================# // Create the keypair $res=openssl_pkey_new(); #echo "openssl_pkey_new:<BR>'$res'<BR><BR>"; // Get private key openssl_pkey_export($res, $privatekey); // Get public key $publickey=openssl_pkey_get_details($res); $publickey=$publickey["key"]; echo "<HR>"; echo "Private Key:<BR>'$privatekey'<br><br>Public Key:<BR>'$publickey'<BR><BR>"; #==============================================================================# echo "<HR>"; $cleartext = '1234 5678 9012 3456'; echo "Klartext:<br>'$cleartext'<BR><BR>"; #------------------------------------------------------------------------------# ### verschluesseln openssl_public_encrypt($cleartext, $crypttext, $publickey); echo "verschluesselter Text:<br>'$crypttext'<BR><BR>"; #------------------------------------------------------------------------------# ### entschluesseln openssl_private_decrypt($crypttext, $decrypted, $privatekey); echo "entschluesselter Text:<BR>'$decrypted'<br><br>"; echo "<HR>"; #------------------------------------------------------------------------------# ?>
