Создадим таблицу для работы, для определенности в схеме SCOTT: CREATE TABLEclosed ( a VARCHAR2 ( 10 ) , b VARCHAR2 ( 10 ) , c VARCHAR2 ( 10 ) ); INSERT INTO closed VALUES ( 'normal1', 'secret', 'normal1' ); INSERT INTO closed VALUES ( 'normal2', 'secret', 'normal2' ); COMMIT;
Для начала рассмотрим обычное хранение строк. Выдадим в SQL*Plus: SQL> SELECT 2 DBMS_ROWID.ROWID_RELATIVE_FNO ( ROWID ) file# 3 , DBMS_ROWID.ROWID_BLOCK_NUMBER ( ROWID ) block# 4 FROM closed SQL> ;
FILE# BLOCK# ---------- ---------- 44
597597
Обе короткие строки попали в один блок на диске. В моем случае это блок № 597 в файле № 4. Подставим полученные значения в команду, которую выдадим от имени SYS: ALTER SYSTEM DUMP DATAFILE 4 BLOCK 597;
Значения двух слов 'secret' в блоке действительно оказались зашифрованы (и стали занимать больше места). Обратите внимание, что шифрование ранее занесенных данных Oracle отрабатывает алгоритмом команды UPDATE, который допускает временное сохранение в блоке старых данных, на радость злоумышленникам (в SQL Server то же самое, если верить интернету).
Выдача значений не раскроет того обстоятельства, что в блоке они хранятся зашифровано: SQL> SELECT * FROM closed; A B C ---------- ---------- ---------- normal1 secret normal1 normal2 secret normal2
Упражнение. Закройте бумажник командой, приведенной выше, и убедитесь, что в этом случае Oracle не сможет показать значение зашифрованного поля B таблицы CLOSED. Откройте бумажник снова для продолжения работы.
Бросается в глаза, что одно и то же значение ('secret') дало разный результат шифрования. Так произошло потому, что для дополнительной защиты Oracle перед шифрованием приписывает к значению случайную последовательность байтов, так называемую «привязку» (salt). Это препятствует расшифровке, и даже лишает возможности злоумышленника понять, что в разных полях исходно были одинаковые значения. С
другой стороны (а) «привязка» замедляет обработку данных и (б) препятствует созданию (древовидного) индекса на шифруемый столбец. Последнее вызвано тем, что значения полей индексируемого столбца помещаются в структуру индекса, и поскольку равные исходные значения будут давать разные шифрованные, индекс не сможет отрабатывать поиск по диапазону, то есть обесценится. Вот Oracle это и запрещает: SQL> CREATE INDEX closed_b ON closed ( b ); CREATE INDEX closed_b ON closed ( b ) * ERROR at line 1: ORA-28338: cannot encrypt indexed column(s) with salt
От применения привязки можно отказаться: ALTER TABLE closed MODIFY ( b ENCRYPT NO SALT );