Oracle10: шифруємо дані






 

Вже давно я таємницю цю
Ховаюся в грудях своїх
І байдужого світу
Не відкрию таємниці цього …
К. Прутков, "Путник"


Зміст



Введення


Сучасні промислові СУБД дозволяють зберігати у своїх базах дані одночасно багатьох користувачів, і тому бажання захистити власні дані від стороннього ока цілком зрозуміло. Деяких рішень цього питання в Oracle були присвячені раніше публікувалися статті Виведені таблиці з збереженим результатом. Частина 1, Виведені таблиці з збереженим результатом. Частина 2, К кожному рядку охоронця приставиш! і В версії Oracle10 "віртуальні приватні бази даних" даних стали виборні. Однак ці рішення Oracle не дозволяють закрити проблему конфіденційності повністю.

Справа в тому, що СУБД Oracle, так само як і інші промислові системи, побудована за принципом суперкористувача, який завжди здатний прочитати всі дані будь-якого користувача. Суперкористувачем в Oracle є SYS. У нього є повноваження ("привілей") SELECT ANY TABLE, а значить він може прочитати дані всіх таблиць в БД. У нього є привілей ALTER USER, а значить він може тимчасово підмінити будь-якому користувачеві пароль, увійти в систему під чужим ім'ям і працювати не можна відрізнити від оригіналу, так що ніякої аудит не виявить несанкціонований доступ. Тим самим співробітник, коториму надано право працювати під ім'ям SYS, повинен бути вкрай довіреною особою в організації, де використовується БД під Oracle. Але чи можна знизити ризик витоку власних даних через суперкористувача?

Відповідь лежить зовні Oracle. Якщо перед приміщенням даних в БД їх зашифрувати, суперкористувач, хоча і прочитає, що зберігається в БД, але нічого не зрозуміє. Зробити це можна в клієнтській програмі, однак для складного додатка організаційно зручніше шифрувати централізованнно, на сервері. Для цієї мети можна скористатися двома пакетами, спеціально призначених в Oracle для роботи з шифрованими даними. Приклади такої роботи наводяться далі.

Пакет DBMS_OBFUSCATION_TOOLKIT


Починаючи з версії 8.1.6 з Oracle поставляється пакет для шифрування і розшифровки методом DES під назвою DBMS_OBFUSCATION_TOOLKIT. Процедурою DESENCRYPT цього пакету можна за допомогою ключа зашифрувати текстову рядок, а процедурою DESDECRYPT розшифрувати.

Приклад в SQL * Plus:

SET SERVEROUTPUT ON

DECLARE
input_string VARCHAR2(4000) := “Morgen, morgen, nur nicht heute”;

work_string VARCHAR2(4000);

encrypted_string VARCHAR2(4000);

decrypted_string VARCHAR2(4000);

BEGIN
DBMS_OUTPUT.PUT_LINE(input_string);

work_string := RPAD
(
   input_string
  , (TRUNC(LENGTH(input_string) / 8) + 1 ) * 8
  , CHR(0)
);

DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT
(
   input_string => work_string
  ,key_string => “MagicKey”
  ,encrypted_string => encrypted_string
);

DBMS_OBFUSCATION_TOOLKIT.DESDECRYPT
(
   input_string => encrypted_string
  ,key_string => “MagicKey”
  ,decrypted_string => work_string
);

decrypted_string := RTRIM(work_string, CHR(0));

DBMS_OUTPUT.PUT_LINE(decrypted_string);
END;
/

Для шифрування використаний восьмібайтовий ключ MagicKey. Так як алгоритм DES працює тільки з рядками, кратними 8 байтам, ми змушені штучно подовжувати вхідні рядок. Для загального випадку в якості доповнюючого символу найбільш природним виглядає CHR (0), хоча в конкретних ситуаціях він може і виявитися неприйнятним. У наступному розділі запропоновано більш сучасне вирішення проблеми доповнюючого символу.

У цьому ж пакеті є аналогічні процедури для більш стійкого алгоритму 3DES, а також для отримання згортки тексту по алгоритму MD5, що можна використовувати для гарантії цілісності даних (захист від несанкціонованої підміни).

Сценарій закладу пакету в БД знаходиться в rdbmsadmincatobtk.sql.

Пакет DBMS_CRYPTO


У версії 10 в склад системних пакетів включений (у перспективі – на заміну DBMS_OBFUSCATION_TOOLKIT) більш функціональний пакет DBMS_CRYPTO, що дозволяє шифрувати дані інших типів (не RAW і VARCHAR2, а RAW, CLOB і BLOB) та іншими алгоритмами (не тільки DES, 3DES, але ще й AES, і RC4, і 3DES_2KEY плюс алгоритми хешування плюс параметризація цих алгоритмів). Він побудований за іншою техніці, коли для шифрування за допомогою лише двох загальні функції ENCRYPT і DECRYPT, а посилання на конкретний алгоритм передається параметром. Ось як за допомогою DBMS_CRYPTO може виглядати DES-шифрування того ж рядка тим ж ключем, що й вище:

DECLARE
input_string VARCHAR2(255) := “Morgen, morgen, nur nicht heute”;
raw_input RAW(4000);

key_string VARCHAR2(8) := “MagicKey”;
raw_key RAW(16);

encrypted_raw RAW(4000);
encrypted_string VARCHAR2(4000);

decrypted_raw RAW(4000);
decrypted_string VARCHAR2(4000);

BEGIN
DBMS_OUTPUT.PUT_LINE(input_string);

raw_input := UTL_I18N.STRING_TO_RAW (input_string, “AL32UTF8”);

raw_key: = UTL_RAW.CAST_TO_RAW (CONVERT (key_string, "AL32UTF8"));

encrypted_raw := DBMS_CRYPTO.ENCRYPT
(
   TYP => DBMS_CRYPTO.DES_CBC_PKCS5
  ,SRC => raw_input
  ,KEY => raw_key
);

decrypted_raw := DBMS_CRYPTO.DECRYPT
(
   TYP => DBMS_CRYPTO.DES_CBC_PKCS5
  ,SRC => encrypted_raw
  ,KEY => raw_key
);

decrypted_string: = UTL_I18N.RAW_TO_CHAR (decrypted_raw, "AL32UTF8");

DBMS_OUTPUT.PUT_LINE(decrypted_string);
END;
/

(Щоб приклад пропрацював, потрібно буде виконати від імені SYS:

CREATE PUBLIC SYNONYM DBMS_CRYPTO TO PUBLIC;

Швидше за все розробники забули вставити цю пропозицію в сценарій закладу пакету і в майбутніх версіях цього нам робити не доведеться).

Тут технологія не вимагає штучного подовження рядка до потрібної кратності, але зате необхідно пред'являти параметри у форматі RAW і в кодуванні AL32UTF8, що теж призводить до ускладнення тексту.

Константа DBMS_CRYPTO.DES_CBC_PKCS5 вище є сума трьох констант ENCRYPT_DES (алгоритм шифрування, розмір ключа), CHAIN_CBC (розмір блоків, на які в процесі шифрування буде розбиватися вихідна рядок) і PAD_PKCS5 (схема доповнення рядка до необхідної кратності). У цьому легко переконатися:

SQL> EXEC DBMS_OUTPUT.PUT_LINE(DBMS_CRYPTO.ENCRYPT_DES)
1

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_OUTPUT.PUT_LINE(DBMS_CRYPTO.CHAIN_CBC)
256

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_OUTPUT.PUT_LINE(DBMS_CRYPTO.PAD_PKCS5)
4096

PL/SQL procedure successfully completed.

SQL> SELECT 1 + 256 + 4096 FROM DUAL;

1+256+4096

           4353

SQL> EXEC DBMS_OUTPUT.PUT_LINE(DBMS_CRYPTO.DES_CBC_PKCS5)
4353

PL/SQL procedure successfully completed.

Щоб у точності відтворити приклад з DBMS_OBFUSCATION_TOOLKIT вище, потрібно буде доповнювати шіфруемих рядок нулями, і тоді замість

TYP => DBMS_CRYPTO.DES_CBC_PKCS5

вказати

TYP => DBMS_CRYPTO.ENCRYPT_DES
         + DBMS_CRYPTO.CHAIN_CBC
         + DBMS_CRYPTO.PAD_ZERO

Вправа. Перевірити, що алгоритм DES реалізований в обох пакетах ідентично, зашифрувавши рядок процедурою DESENCRYPT пакету DBMS_OBFUSCATION_TOOLKIT, а розшифрувавши функцією DECRYPT пакету DBMS_CRYPTO.

Тим не менш, сучасна технологія не рекомендує на практиці доповнювати рядок нулями, а радить користуватися схемою доповнення PKCS5.

Приклад вказівки алгоритму шифрування AES ключем в 128 розрядів:

TYP => DBMS_CRYPTO.ENCRYPT_AES128
         + DBMS_CRYPTO.CHAIN_CBC
         + DBMS_CRYPTO.PAD_PKCS5

Інші можливості пакету DBMS_CRYPTO наведені в документації.


Посилання по темі



Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*