Most akkor van vagy nincs?
Adatbázis adatszintű titkosítás
Pár hete egy pályázat kapcsán az ajánlatkérő elvárta tőlünk, hogy mutassuk be neki a Microsoft SQL Server és Oracle adattitkosítási lehetőségeit. Ebből kifolyólag néztem utána a témának.
Összességében elmondhatom, hogy ha csak lehet elhárítom az adatbázisban lévő adatok titkosítását. Ez ugyanis (bármely adatbázis-kezelőről is van szó) eléggé megnehezíti és elbonyolítja a fejlesztést. Azt pedig nem szeretjük. Nehezebb a kódot karbantartani, több a hibalehetőség, csökkenti az alkalmazás sebességét és növeli a fejlesztési költségeket. Persze, ha nincs más lehetőség…
Nézzük előbb az SQL Server-t. Nagyon egyszerű a dolog, hiszen az adatkezelő rétegben (már ha van ilyen) a karbantartó INSERT, UDATE SQL-utasításokban egyszerűen csak használni kell az erre a célra létező "Encrypt…", a SELECT-ben pedig a "Decypt…" tárolt függvényeket. Így pl.: EncryptByCert(), DecryptByCert(), EncryptByAsymKey(), DecryptByAsymKey(), EncryptByKey(), DecryptByKey(), EncryptByPassPhrase(), DecryptByPassphrase(), stb.
Ezek a függvények futás közben képesek az adatot titkosítani vagy visszafejteni. A titkosítás lehet szimmetrikus, aszimmetrikus, vegyes és/vagy tanúsítvány alapú. Titkosítani úgy lehet adatot, hogy a bizalmas (pl.: a főnök fizetését tartalmazó) oszlopnevet az INSERT, UPDATE során egyszerűen be kell csomagolni egy ilyen függvényhívásba (mondjuk triggeren vagy tárolt eljáráson belül). Ezután a titkosított adat az az adatbázison belül egyszerű lekérdezések által nagyjából mindenki számára láthatatlan marad (legalábbis azok számára, akik nem férnek hozzá a kulcsokhoz, tanúsítványokhoz).
Titkosított adatot visszafejteni pedig úgy lehet, hogy nézetbe vagy tárolt eljáráson/függvényen belül a titkos oszlopnevet a SELECT-en belül be kell ágyazni a visszafejtő függvénybe (persze a titkosító kulcsok kezelése, hozzáférhetősége itt is megérne egy misét, mert elég nehézkes, de azt hiszem most inkább hagyjuk).
Természetesen az Oracle is tartalmaz beépített titkosító/visszafejtő függvényeket. Náluk két csomag (package) is a rendelkezésre áll, melyek nagyjából ugyanazt és ugyanúgy tudják, mint az SQL Server esetén már említve volt. Ez a két csomag a DBMS_OBFUSCATION_TOOLKIT és a DBMS_CRYPTO. Ezeknek van mindenféle "Encrypt…" meg "Decrypt…" függvénye, melyekkel a kívánt művelet elvégezhető. Ezeken belül szabályozható az algoritmus (ENCRYPT_DES, ENCRYPT_3DES_2KEY, ENCRYPT_3DES, ENCRYPT_AES128, ENCRYPT_AES192, ENCRYPT_AES256, ENCRYPT_RC4 ) vagy pedig bizonyos feltöltési szabályok (PAD_ZERO, PAD_PKCS5).
A használati mód ugyanaz, mint az SQL Server esetén (triggerek, beágyazott függvények és eljárásokban lévő SQL-utasítások).
Álljon itt példaként egy titkosítási feladat (Oracle SQL*Plus-ból végrehajtva):
DECLARE
sKulcs VARCHAR2(2000) := ‘1234567890123456’;
sTitok VARCHAR2(2000) := ‘BizalmasAdat’;
sTitkos RAW(2000);
nOpcio NUMBER := dbms_crypto.ENCRYPT_AES128+dbms_crypto.CHAIN_CBC+dbms_crypto.PAD_PKCS5;
BEGIN
sTitkos:=dbms_crypto.encrypt(UTL_I18N.STRING_TO_RAW(sTitok,’AL32UTF8′), nOpcio,
UTL_I18N.STRING_TO_RAW(sKulcs, ‘AL32UTF8’));
dbms_output.put_line(‘Titkosítva=’||sTitkos);
END;
Titkosítás utáni adat: C0777257DFBF8BA9A4C1F724F921C43C70D0C0A94E2950BBB6BA2FE78695A6FC
Az Oracle ezen kívül tartalmaz még egy Transparent Data Encryption (TDE) nevű érdekes módszert is. Ennek az a lényege, hogy a felhasználó számára átlátszó (transzparens) módon, röptében titkosítja és fejti vissza az adatokat. A működéséhez az oszlop deklarációnál kell megmondani, hogy az Oracle titkosítson-e vagy sem, illetve ha igen, akkor mit/hogyan csináljon az adattal.
Pl.: CREATE TABLE Titok (titkos_adat VARCHAR2(10) ENCRYPT);
Ennél persze összetetteb is lehet (milyen algoritmus, milyen kulcs, a kulcsot fűszerezze-e vagy sem, stb). Értelemszerűen az Oracle INSERT, UPDATE esetén röptében titkosít, SELECT esetén pedig azonnal visszafejt. Itt egy táblázat arra nézve, hogy menet közben ez mekkora időveszteséget jelenthet a folyamatoknak:
Művelet Normál tábla Titkos tábla Eltérés %
INSERT 00:06:00.94 00:08:12.75 26.7 %
CREATE INDEX 00:00:04.70 00:00:18.58 37 %
COUNT(*) utasítás 00:00:00.07 00:00:00.10 30 %
SELECT utasítás 00:00:11.18 00:00:21.77 48.6 %
Vagyis kb. az eltérés százaléknál látható mértékű lassulást okozhat egy ilyen titkosítási/visszafejtési művelet.
A TDE működéséhez telepíteni kell egy úgynevezett Oracle "Wallet" komponenst, amely a tanúsítványokat, jelszavakat és kulcsokat menedzseli. Ezen kívül még át kell állítani néhány rendszerszintű paramétert is (ALTER SYSTEM…).
Ez utóbbi lehetőség azonban nagyjából semmire se jó. Legalábbis nekünk nem. Azért, mert az említett módszer nem az adatbázis felhasználója, hanem a hekker, tolvaj és hasonló rosszindulatú emberfajta elől rejti el az adatokat. Vagyis a fájlokba, fizikai szinten titkosítva kerül be az adat. Bárki ellopja az Oracle-t semmire se megy a titkosított adatokkal és visszafejteni se tudja. Ennélfogva ez inkább egy biztonsági kiegészítés és nem az, amire normál esetben szükség volna. Mivel nem csak az INSERT, UPDATE esetén titkosít, hanem a SELECT esetén is visszafejt, méghozzá röptében, így a felhasználó mindig az eredeti, titkosítatlan adatot látja. Ez teljesen logikus viselkedés.
Úgy emlékszem, hogy az SQL Server alatt is van ilyen, de ennek már nem néztem utána, mivel a számomra most nem lényeges (bár attól még lehet hasznos).
Következtetés? Hát az van.
Az utolsó pontban említett Oracle – TDE csak biztonsági szempontból hasznos annak, aki erre gerjed be. Az előtte lévő pontokban vázolt (MSSQL és Oracle) függvény alapú titkosításokat azonban bizonyos problémák miatt nehéz alkalmazni. Pontosabban új szoftverek esetén, vagy meglévő, tárolt eljárásokra alapuló adatkezelés esetén könnyen be lehet építeni, de régóta létező és esetleg nem is többrétegű programokat sajnos csak hosszadalmas (meg költséges) módosítások árán lehet felkészíteni rá.
További nehézség, hogy a titkosítandó adat formátuma miután titkosítva lett nem INTEGER, VARCHAR, DATE, meg efféle, hanem (Oracle esetén pl.) értelemszerűen úgynevezett RAW bájtsorozat. Vagyis nyilvánvaló, hogy a titkosított adatot NEM lehet az eredeti oszlopban tárolni, mert nem ugyanolyan típusú. Akkor se lehetne, ha nem RAW, hanem VARCHAR lenne, mivel pl. egy DATE oszlopba nem lehet tartalmilag és típusát tekintve nem odaillő adatot beletuszkolni (ráadásul a RAW se kompatibilis a VARCHAR-al). Vagyis nincs olyan, hogy eredeti meg titkosított oszlop, hanem csak titkosítot oszlop lehet és kész.
Példa:
– dátum: 2007.04.17 (DATE),
– ugyanez titkosítva: AG76576H683NBV92333FGG vagy valami hasonló (RAW).
Ez utóbbra csak az lehet a megoldás, ha eleve RAW (MSSQL-en meg más) típusú lenne minden titkosított oszlop. Ekkor viszont az összes programnak, tároltnak, SELECT-nek bárhol is van az, amikor hivatkozik egy ilyen oszlopra úgyanúgy használnia kellene a visszafejtő függvényeket, ráadásul az alkalmazásoknak ügyelniük kell arra is, nehogy a képernyőn lévő adatmezőbe véletlenül RAW típusú adat érkezzen.
Csak azért nyavalyogtam ennyit, mert nekem most azt kellene megoldanom, hogy egy 13 éve létező, 150 vállalatnál/intézménynél műküdő, több százezer soros ERP rendszer ily módon legyen felvértezve, az adatbázis alapú titkosítás képességeivel. Ja és mindehhez ne kelljen a programozóknak csinálniuk lehetőleg semmit (mert az pénzbe és időbe kerül a cégnek), valamint a megbízhatóságon és használhatóságon se essen túl sok csorba. Nyomozok tovább…
Hivatkozások:
Hozzászóláshoz be kell jelentkezni!