Aus Linux-Magazin 09/2007

Datenverschlüsselung mit Oracle

© pixelio.de

Datenbanken enthalten oft sensible Daten. Die sind aber ungeschützt, wenn ein Hacker an die Datenbank-Files oder ein Backup gelangt. Sicherheitsvorkehrungen in Oracle beheben diesen Mangel durch einfach zu konfigurierende Verschlüsselungsmechanismen.

Üblicherweise steht ein Datenbankserver hinter einer Firewall als erstem Sicherheitsbollwerk gegen unberechtigte Zugriffe. Als zweiter Schutzwall dienen die Passwörter und die damit verbundenen Zugriffsberechtigungen auf die Datenbank. Doch beide Ebenen schützen noch immer nicht die Daten selbst, die in Plaintext als Data-Files auf der Festplatte liegen oder in dieser Form durch Datennetze wandern. Kommt gar ein Unbefugter an ein unverschlüsseltes Datenbank-Backup, stehen auch die geheimsten Informationen binnen weniger Stunden auf einem fremden Server wieder zur Verfügung.

Dieser Artikel erläutert, wie sich Datenbankdaten zwischen Client und Server und auf der Festplatte verschlüsseln lassen. Er beschreibt beispielhaft einige einfache und schnell realisierbare Lösungsmöglichkeiten, die Oracle bereits für diesen Zweck anbietet.

Die Zuständigkeit für die Kommunikation zwischen Oracle-Client und -Server liegt bei dem Protokoll SQL*Net. Der Client meldet sich über dieses Protokoll beim Listener an, der auf Connections wartet. Anschließend verbindet der Listener den Client dezidiert oder im Shared-Modus mit der Datenbank und klinkt sich wieder aus.

Bei einer Standardinstallation kommunizieren Client und Server ganz ohne Verschlüsselung. Abbildung 1 demonstriert, dass ein Fremder, der den übertragenen Plaintext mitlesen kann, den Inhalt ohne Weiteres vor sich sieht. Oracle kennt allerdings auch verschiedene Verfahren für eine sichere, sprich eine verschlüsselte Kommunikation. Zusätzlich lassen sich die chiffrierten Daten auch noch durch eine Prüfsumme gegen Verfälschung schützen.

Abbildung 1: Eine Übertragung der Datenbankinhalte als Plaintext kann jedermann sehr einfach mitlesen.

Abbildung 1: Eine Übertragung der Datenbankinhalte als Plaintext kann jedermann sehr einfach mitlesen.

Dieser Beitrag greift nur die kürzeste Methode zur Verbesserung der Sicherheit heraus. Daneben existieren noch andere Verfahren, die zum Beispiel SSL oder das Zertifikat X.509 benutzen oder auf Sicherheitsmechanismen innerhalb des JDBC-Treibers setzen.

Datenkarawanen tarnen

Voraussetzung für eine Verschlüsselung in Oracle ist die inzwischen standardmäßig installierte Advanced Security Option (ASO). Mit dem Kommando »adapters« (unter »$ORACLE_HOME/bin« zu finden) lässt sich feststellen, ob diese Option installiert ist oder nicht. Die Konfiguration erledigt entweder der grafische Oracle Network Manager »netmgr« oder der Anwender editiert händisch die Datei »sqlnet.ora«, sodass sie anschließend folgende Zeilen enthält:

SQLNET.ENCRYPTION_SERVER = required
SQLNET.CRYPTO_SEED = asdfghj12345teg
SQLNET.ENCRYPTION_TYPES_SERVER= (AES256,3DES168,RC4_128)

Der Parameter »SQLNET.ENCRYPTION_SERVER« legt fest, wie streng der Server mit der Verschlüsselung umgeht.

Dafür stehen vier Optionen zur Verfügung: »required« bewirkt, dass der Server die Kommunikation abbricht, wenn der Client keine Verschlüsselung versteht. Mit »requested« versucht der Server verschlüsselt zu kommunizieren, wann immer es möglich ist. Dafür muss auf der Gegenseite »required«, »requested« oder »accepted« definiert sein. Versteht ein Client keine Verschlüsselung, schickt der Server die Daten in Plaintext.

Mit »accepted« verschlüsselt der Server, wenn die andere Seite auf »required« oder »requested« gesetzt ist. Die vierte Option »rejected« meint schließlich, dass die Kommunikation in diesem Fall auf keinen Fall verschlüsselt sein darf.

Der Parameter »SQLNET.CRYPTO_SEED« steht für die Schlüssellänge. Er enthält eine beliebige Zeichenkette mit zehn bis 70 Zeichen. Der Parameter »SQLNET.ENCRYPTION_TYPES_SERVER« verlangt einen oder mehrere Verschlüsselungsalgorithmen als Wert – die möglichen Optionen dafür listet die Tabelle 1 auf. Der Server versucht dann in den aufgezählten Optionen von links nach rechts einen passenden Algorithmus zur Kommunikation zu finden. Der stärkste Algorithmus sollte daher in der Werteliste an erster Stelle stehen.

Tabelle 1:
Verschlüsselungsalgo-rithmen für SQL*Net

 

Verfahren

Schlüssellänge

Kürzel

RSA

RC4 256 Bit

RC4_256

 

RC4 128 Bit

RC4_128

 

RC4 56 Bit

RC4_56

 

RC4 40 Bit

RC4_40

AES

AES 256 Bit

AES256

 

AES 192 Bit

AES192

 

AES 128 Bit

AES128

Triple DES

3 Key 3DES

3DES168

 

2 Key 3DES

3DES112

 

DES 56 Bit

DES

 

DES 40 Bit

DES40

Der Fehlermeldung »ORA-12645 Parameter does not exist« entgeht man durch doppelte Hochkommas um den Wert des Parameters »SQLNET.CRYPTO_SEED«. Wenn jetzt ein Unbefugter mit einem Sniffer den Datentransfer belauscht, erkennt er nur noch völlig unleserliche Zeichenketten (Abbildung 2).

Abbildung 2: Verschlüsselt ist der Datenverkehr für neugierige Lauscher nur noch eine unverständliche Folge von Bytes.

Abbildung 2: Verschlüsselt ist der Datenverkehr für neugierige Lauscher nur noch eine unverständliche Folge von Bytes.

Eingeschriebene Pakete

Eine Prüfsummen-Funktion stellt auf Wunsch zusätzlich sicher, dass niemand die Daten während der Übertragung verfälschen kann, und verhindert damit die gefährlichen Man-in-the-Middle-Angriffe. Jeder Block erhält dabei eine eindeutige kryptographische Prüfsumme auf den Weg, die die Empfängerseite zum Vergleich neu berechnet. Erst die Übereinstimmung dieser Summen bestätigt dann, dass die Pakete höchstwahrscheinlich unversehrt geblieben sind.

Die Konfiguration dieser Funktion erfolgt genauso wie die Verschlüsselung entweder über den »netmgr« oder durch Editieren von »sqlnet.ora«. Für die Prüfsummen stehen die Algorithmen SHA1 und MD5 zur Verfügung. Die beiden Zeilen

SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER= (SHA1, MD5)
SQLNET.CRYPTO_CHECKSUM_SERVER= required

in »sqlnet.ora« aktivieren schließlich die Prüfsummen.

Geschlossene Gesellschaft

Eine dritte Möglichkeit zur sicheren Datenübertragung ist die Beschränkung des Zugriffs auf bestimmte IP-Adressen. Diese Art der Zugriffskontrolle setzt voraus, dass Client und Server über SQL*Net und das TCP/IP-Netzwerkprotokoll kommunizieren. Einzustellen ist das wiederum über »netmgr« oder in »sqlnet.ora« mit den folgenden Zeilen:

TCP.VALIDNODE_CHECKING=YES
TCP.INCLUDED_NODES=(192.168.0.117,db.nachbar.com, db.freund.at)

Alles oder nichts

Bisher zeigte dieser Beitrag, wie die Datenbank vor unberechtigten Zugriffen zu schützen ist. Die Datenbankdateien selbst ließen sich dabei aber immer noch lesen, im einfachsten Fall mit dem gewöhnlichen Kommando »strings« (Abbildung 3). Die Gefahr ist besonders groß, wenn Backup-Dateien, die auf anderen und schlechter geschützten Servern lagern, dem Angreifer in die Hände fallen. Oft ist für die Sicherheit dort auch ein anderer Administrator zuständig.

Abbildung 3: Ein Data-File gibt selbst dem einfachen Kommando »strings« seinen Inhalt ohne viele Umstände preis.

Abbildung 3: Ein Data-File gibt selbst dem einfachen Kommando »strings« seinen Inhalt ohne viele Umstände preis.

Um diese Lücke zu schließen, verschlüsselt der Admin die Datenbank-Files am besten in jedem Fall. Aber Achtung: Auf Betriebssystemebene darf er das auf keinen Fall tun, denn dann könnte auch Oracle nichts mehr mit ihnen anfangen [1]. Das Mittel der Wahl ist eine Datenbank-interne Methode. Oracle kennt davon zwei: Transparent Data Encryption (TDE) ab Version 10g (Release 2) und die Verschlüsselung mit Hilfe des Package DBMS_CRYPTO ab Oracle 10g oder des DBMS_OBFUSCATION_TOOLKIT in früheren Versionen.

Bei DBMS_CRYPTO muss der Admin (im Gegensatz zu TDE) jedoch programmieren, zum Beispiel eine neue Funktion für die Ausführung der Verschlüsselung. Das bedingt eine Änderung aller SQL-Statements, die die verschlüsselten Daten betreffen, auf Applikationsebene (Abbildung 4). DBMS_CRYPTO unterstützt bei der Verschlüsselung nicht die Datentypen »NUMBER« und »DATE«. Ein Beispiel für eine solche Funktion könnte wie in Listing 1 aussehen.

Abbildung 4: Jedes SQL-Statement einer Anwendung muss bei dieser Methode so modifiziert werden, dass es die Verschlüsselung benutzt.

Abbildung 4: Jedes SQL-Statement einer Anwendung muss bei dieser Methode so modifiziert werden, dass es die Verschlüsselung benutzt.

Listing 1:
Verschlüsselungsfunktion

01 CREATE OR REPLACE FUNCTION CRYPT_F
02 (eingabe IN VARCHAR2 ) RETURN RAW
03 AS
04 schluessel VARCHAR2(64)
05 :='1234567890abcd1517ab54ab6d8e8e9e6e5e4e4a3a4a5a6a7a8a4a9a4a3a1a';
06
07 sh1 CONSTANT PLS_INTEGER :=             DBMS_CRYPTO.HASH_SH1 +
08 DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_ZERO;
09 konvertiere_schluessel RAW(64);
10 konvertiere_eingabe RAW(64);
11 entsch_eingabe RAW(64);
12 
13 BEGIN
14 konvertiere_eingabe := UTL_I18N.STRING_TO_RAW(eingabe, 'AL32UTF8');
15 
16 konvertiere_schluessel := UTL_I18N.STRING_TO_RAW(schluessel,'AL32UTF8');
17 
18 entsch_eingabe := DBMS_CRYPTO.ENCRYPT( src => konvertiere_eingabe, typ=> sh1,
19  key => konvertiere_schluessel, iv => NULL);
20 
21 RETURN entsch_eingabe;
22 end;
23 
24 
25 CREATE OR REPLACE FUNCTION DECRYPT_F ( eingabe IN VARCHAR2 )
26 RETURN VARCHAR2
27 AS
28 sh1 CONSTANT PLS_INTEGER :=DBMS_CRYPTO.HASH_SH1 + DBMS_CRYPTO.CHAIN_ECB +
29 DBMS_CRYPTO.PAD_ZERO;
30 konvertiere_eingabe VARCHAR2(64);
31 schluessel VARCHAR2(64) :=
32 '1234567890abcd1517ab54ab6d8e8e9e6e5e4e4a3a4a5a6a7a8a4a9a4a3a1a';
33 konvertiere_schluessel RAW(64);
34 entschl_eingabe VARCHAR2(64);
35 
36 BEGIN
37 konvertiere_eingabe := UTL_I18N.STRING_TO_RAW(eingabe, 'AL32UTF8');
38 konvertiere_schluessel := UTL_I18N.STRING_TO_RAW(schluessel,'AL32UTF8');
39 
40
41 entschl_eingabe := DBMS_CRYPTO.DECRYPT(src => eingabe,typ => sh1,key
42 => konvertiere_schluessel,iv => NULL);
43 konvertiere_eingabe := UTL_I18N.RAW_TO_CHAR(entschl_eingabe,'AL32UTF8');
44 
45 
46 RETURN konvertiere_eingabe;
47 
48 END;

Diese Funktion bietet allerdings noch keinen ausreichenden Schutz, ein erfahrener Datenbank-Administrator kann in kürzester Zeit die Strukturen dieses Verschlüsselungsmechanismus erkennen. Eine bessere und sicherere Methode ist die TDE. Mit TDE ist keine zusätzliche Funktionen notwendig und sie erfordert keine Änderungen auf der Applikationsebene.

Um TDE zu nutzen, erzeugt der Administrator einen Schlüssel, den Oracle nicht im Data-Dictionary, sondern im Filesystem ablegt. Nur mit diesem Schlüssel lassen sich die Daten speichern oder lesen. Der erste Schritt besteht wiederum aus einigen Einträgen in der Datei »sqlnet.ora«. Diese Zeilen sollten folgendermaßen aussehen:

ENCRYPTION_WALLET_LOCATION =
 (SOURCE=
  (METHOD=file)
   (METHOD_DATA=
    (DIRECTORY=/data/oracle/wallet)))

Der Eintrag definiert, dass das Verzeichnis »wallet« das Speicherziel für die erzeugten Keys ist. Im zweiten Schritt ist das Encryption Wallet per SQL-Kommando zu öffnen. Dafür ist eine »ALTER SYSTEM«-Berechtigung erforderlich:

SQL>ALTER SYSTEM SET ENCRYPTION KEY AUTHENTICATED BY "passwort";
SQL>ALTER SYSTEM SET ENCRYPTIONWALLET open AUTHENTICATED by "passwort";

Achtung: Das Wallet muss der Admin nach jedem Restart der Datenbank erneut öffnen.

Anschließend geht es um die Datenverschlüsselung selbst. Als Erstes sind jene Spalten einer Tabelle, für die eine Verschlüsselung gewünscht ist, vorzubereiten. Im folgenden Beispiel soll das die Spalte »strasse« betreffen:

SQL>ALTER TABLE kunden MODIFY (strasse ENCRYPT USING 'AES128');

Das Beispiel verwendet den Verschlüsselungsalgorithmus AES128, standardmäßig wird AES mit einem 192 Bit langen Schlüssel benutzt. Weitere verfügbare Algorithmen nennt Tabelle 2.

Tabelle 2:
Verschlüsselungsalgo-rithmen für TDE

 

Name

Schlüsselgröße

Parametername

AES

128 Bit

AES128

AES

192 Bit

AES192

AES

256 Bit

AES256

Triple DES

168 Bit

3DES168

Das Salz in der Suppe

Eine verschlüsselte Spalte kann einem aufmerksamen Eindringling dennoch Informationen liefern. Beim Verschlüsseln zum Beispiel der Gehaltsspalte einer Mitarbeitertabelle würden dieselben Gehälter auch mit denselben Werten verschlüsselt. Die absolute Höhe des Einkommens bliebe zwar verborgen, ein Angreifer könnte aber zumindest immer noch ablesen, welche und wie viele Mitarbeiter gleich viel verdienen.

Um dies zu verhindern, lässt sich in Oracle die Verschlüsselung mit einem Salt-Wert verbessern, der gleiche Werte unterschiedlich verschlüsselt. TDE salzt per Default, allerdings ist zu bedenken, dass sich eine Spalte, die an einem Index beteiligt oder ein Primary Key ist oder Unique Values enthält, nur einfach – ohne Salt – verschlüsseln lässt.

Wer es trotzdem versucht, dem meldet Oracle: »ORA-28338: cannot encrypt indexed column(s) with salt«. Umgekehrt ist es auch nicht möglich, eine mit Salz verschlüsselte Spalte zu indizieren. Um einen Index anzulegen, muss der Anwender vorher die Verschlüsselung also entsalzen:

alter table tablename modify (columnname encrypt no salt);

Wer verschlüsselte Daten mit »expdp« exportieren will, muss aufpassen. Ohne ein zusätzliches Kommando würde »expdp« die Daten vorher entschlüsseln und in Plaintext exportieren. Expdp bietet aber die Möglichkeit, dies mit dem Parameter »ENCRYPTION_PASSWORD« zu verhindern. Verschlüsselte Spalten bleiben dann verschlüsselt. Derselbe Parameter ist auch beim Import mit »impdp« zu verwenden.

Fazit

Datenschutz ist keine triviale Angelegenheit. Mit der entsprechenden Sorgfalt und den geeigneten Tools kann der Oracle-Admin jedoch eine hohe Sicherheitsstufe sowohl bei der Datenspeicherung als auch bei der Datenübertragung erreichen. Natürlich erkauft er den Ver- und Entschlüsselungsvorgang mit einem gewissen Performanceverlust. Aus diesem Grund ist es empfehlenswert, nicht pauschal alles, sondern ganz gezielt nur die sensibelsten Spalten einer Tabelle zu verschlüsseln. (jcb)

Infos

[1] Peter Gutmann und Christian Ney, “Geheime Geschäfte”: Linux-Magazin 03/07, S. 82

[2] Advanced Security Administrator\’s Guide 10g Release2 Part No. B14268-02

[3] Security Guide 10g Part No. B10773-01

Der Autor

Mag. Badran Farwati arbeitet als Datenbankadministrator und -Programmierer in der Österreichischen Nationalbibliothek und beteiligt sich außerdem in seiner Freizeit an mehreren Open-Source-Projekten.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben