Oracle 11g предоставляет такие нововведения, как регистрозависимые пароли, прозрачное шифрование табличных пространств, списки доступа к UTL_TCP/HTTP/SMTP.
Пароли по-умолчанию
Oracle Database 11g предоставляет возможность быстро определить пользователей с паролем по-умолчанию, для этого требуется выполнить простой запрос к представлению словаря данных: DBA_USERS_WITH_DEFPWD. Отметим, что префикс DBA_ является стандартным и не означает, что в представлении указаны только пользователи DBA с паролем по-умолчанию. Для определения пользователей со стандартным паролем выполняем:
SELECT *
FROM DBA_USERS_WITH_DEFPWD;
Результатом выполнения будет примерно такой список пользователей (если, вы не изменили пароль для пользователей ранее):
USERNAME
------------------------------
DIP
MDSYS
WK_TEST
CTXSYS
OLAPSYS
OUTLN
EXFSYS
SCOTT
MDDATA
ORDPLUGINS
ORDSYS
XDB
LBACSYS
SI_INFORMTN_SCHEMA
WMSYS
Как видно, пользователь SCOTT с его паролем TIGER присутствует в списке. Изменим пароль, что бы проверить, что действительно перечислены пользователи с паролем назначенным по-умолчанию:
ALTER USER SCOTT IDENTIFIED BY TIGER1;
User altered.
Проверяем представление:
SELECT *
FROM DBA_USERS_WITH_DEFPWD;
Получаем результат и видим, что пользователя SCOTT в нем уже нет.
Регистрозависимые пароли
До версии Oracle 11g, регистр пароля не имел значения, например, выполним следующие инструкции в Oracle 10g:
SQL> CONN scott/tiger
Connected.
SQL> CONN scott/TIGER
Connected.
Такое положение вещей представляет проблему при соответствии стандартам, например Payment Card Industry (PCI) Data Security Standard, который требует регистрозависимые пароли.
В 11 версии эта проблема решена, теперь при создании базы данных средствами утилиты DBCA, будет предложено обновить систему защиты к новым стандартам. Одним, из которых является регистрозависиммость пароля.
Ниже представлен результат перехода к новым стандартам безопасности:
SQL> conn scott/tiger
Connected.
SQL> conn scott/TIGER
ERROR:
ORA-01017: invalid username/password; logon denied
Warning: You are no longer connected to ORACLE.
Из примера видно, что теперь "tiger" и "TIGER" не одно и то же.
Многие разработчики используют в формах регистрации перевод пароля к верхнему регистру, теперь это придется исправить.
При желании можно вернуться к независящим от регистра паролям. Для этого требуется изменить значение системного параметра SEC_CASE_SENSITIVE_LOGON, как показано в примере ниже:
SQL> conn / as sysdba
Connected.
SQL> ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = FALSE;
System altered.
SQL> conn scott/TIGER
Connected.
При обновлении базы данных Oracle 10g до Oracle 11g, можно провести миграцию паролей к новому стандарту. Проверить статус пароля можно выполнив запрос к представлению DBA_USERS, включив в выборку колонку PASSWORD_VERSIONS:
SELECT USERNAME, PASSWORD, PASSWORD_VERSIONS
FROM DBA_USERS;
USERNAME PASSWORD PASSWORD
------------------------- ------------------------------ --------
SYSTEM 10G 11G
SYS 10G 11G
MGMT_VIEW 10G 11G
Первое, что сразу бросается в глаза, это NULL-значения в колонке PASSWORD, которая обычно заполнена хешированными значениями, как например в Oracle 10g. Эти значения хранятся в таблице USER$, но невидимы в представлении DBA_USERS. При создании нового пользователя, в зависимости от аутентификации отображается статус GLOBAL или EXTERNAL, но хешированные значения паролей не отображаются. Колонка PASSWORD_VERSIONS появилась в Oracle 11g, и показывает регистрозависимость пароля. Так значение "10G 11G" указывает, что пользователь создан ранее в Oracle 10g и мигрирован в Oracle 11g или создан напрямую в Oracle 11g.
Можно сделать зависимым от регистра пароль SYSDBA, указанием параметра ignorecase, при создании файла паролей, как показано ниже:
$ orapwd file=orapwPRODB3 password=abc123 entries=10 ignorecase=n
В показанном примере пароль будет abc123, а не ABC123, или какие либо другие вариации регистра.
Зависимость пароля от регистра усложняет взлом пароля перебором.
Профили и функции проверки пароля
В Oracle Database 11g функции управления паролями имеют новую и усовершенствованную логику верификации. Если рассмотреть файл utlpwdmg.sql расположенный в $ORACLE_HOME/rdbms/admin вы увидите, что этот скрипт создает новую функцию верификации пароля verify_fnction_11g. В конце скрипта есть строки:
ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME 180
PASSWORD_GRACE_TIME 7
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LOCK_TIME 1
PASSWORD_VERIFY_FUNCTION verify_function_11G;
Скрипт привязывает функцию к профилю DEFAULT, который является профилем по-умолчанию для всех пользователей, если иное не указано явно. Это делает аутентификацию совместимой с многими правилами. Все что вам надо сделать - запустить скрипт на исполнение, и он создаст функции проверки версии 11g, а так же разрешит функции верификации пароля, прикреплением их к профилю по-умолчанию.
Улучшенный аудит
В Oracle 11g два простых нововведения позволили улучшить аудит БД. Первое, это значение параметра audit_trail по-умолчанию установлено в DB, а не NONE, как было в предыдущих версиях. Это позволяет включить аудит любых объектов, предложений или привилегий без перезапуска базы данных.
Второе изменение, это увеличение количества предложений, которые могут подвергаться аудиту, ниже представлен список:
ALTER SYSTEM
SYSTEM AUDIT
CREATE SESSION
CREATE USER
ALTER USER
DROP USER
ROLE
CREATE ANY TABLE
ALTER ANY TABLE
DROP ANY TABLE
CREATE PUBLIC DATABASE LINK
GRANT ANY ROLE
ALTER DATABASE
CREATE ANY PROCEDURE
ALTER ANY PROCEDURE
DROP ANY PROCEDURE
ALTER PROFILE
DROP PROFILE
GRANT ANY PRIVILEGE
CREATE ANY LIBRARY
EXEMPT ACCESS POLICY
GRANT ANY OBJECT PRIVILEGE
CREATE ANY JOB
CREATE EXTERNAL JOB
При обновлении до Oracle 11g, по-умолчанию, аудит включен для вышеупомянутых предложений. Записи аудита хранятся в таблице AUD$, в табличном пространстве SYSTEM, следует быть готовым к быстрому заполнению табличного пространства и настроить аудит БД.
Прозрачное шифрование табличных пространств
Шифрование табличных пространств требует внимательности и аккуратности, любое неверное действие сейчас, может плачено обернуться в будущем.
В Oracle Database 10g Release 1 и в предыдущих версиях инструментарий DBMS_CRYPTO и DBMS_OBFUSCATION_TOOLKIT предоставлял инфраструктуру шифрования. В Oracle Database 10g Release 2, эта инфраструктура трансформировалась в прозрачное шифрование данных (Transparent Data Encryption).
Шифрование данных позволяет шифровать некоторые колонки, удовлетворяющие многим условиям. На шифрованные данные накладывался ряд ограничений.
В Oracle 11g если табличное пространство описано как шифрованное, то любые данные в нем (включая переносимые табличные пространства, резервные копии и т.д.) помечены как шифрованные, и это не то же самое, что шифровать их по отдельности. Но во время сканирования индекса, сканирование происходит в памяти, где данные не зашифрованы, и как следствие нет воздействия на производительность.
Как это происходит? Процедура шифрования аналогична шифрованию данных, требуется создать бумажник, в котором будет сохранен ключ.Первое, создайте место для расположения бумажника, размещение по умолчанию $ORACLE_BASE/admin//wallet, но поддиректории бумажника по-умолчанию нет, требуется создать ее. В примере разместим бумажник в:
/home/oracle/app/admin/PRODB3/wallet
Второе, создаем ключ шифрования:
ALTER SYSTEM SET ENCRYPTION KEY IDENTIFIED BY "abcd1234!";
Это предложение создает и бумажник и ключ. Если проверить содержимое директории, то в ней будет файл ключа (ewallet.p12):
$ cd /home/oracle/app/admin/PRODB3/wallet
$ ls
ewallet.p12
Бумажник может быть открыт только паролем. В примере, abcd1234. Это предложение, так же открывает бумажник, в последствии не требуется его создавать а требуется только открыть, выполнив:
ALTER SYSTEM SET WALLET OPEN IDENTIFIED BY "abcd1234!";
Далее создаем табличное пространство:
CREATE TABLESPACE SECURE1
DATAFILE '/home/oracle/oradata/PRODB3/secure1_01.dbf'
SIZE 1M
ENCRYPTION USING 'AES128'
DEFAULT STORAGE (ENCRYPT)
Предложение " CREATE TABLESPACE … STORAGE (ENCRYPT)" помечает табличное пространство как шифрованное, в примере используется шифрование ключом AES 128-bit. Так же можно выбрать: DES 168-bit ключ, AES 192-bit ключ и AES 256-bit ключ.
Теперь, когда табличное пространство создано, создаем таблицы:
CREATE TABLE SECURE_TRANS
TABLESPACE SECURE1
AS
SELECT * FROM TRANS
WHERE ROWNUM < 201
/
CREATE TABLE SECURE_RES
TABLESPACE SECURE1
AS
SELECT * FROM RES
WHERE ROWNUM < 201
Оба предложения создают таблицы внутри зашифрованного табличного пространства SECURE1. Для сравнения, создайте обычное (не зашифрованное) табличное пространство, назовите его INSECURE1 и создайте таблицы INSECURE_TRANS и INSECURE_RES. Таблицы INSECURE_TRANS и SECURE_TRANS абсолютно идентичны, по содержимому, но размещены в разных табличных пространствах. То же самое касается таблиц SECURE_RES и INSECURE_RES.
Сейчас обновим текстовое поле в таблицах, так что бы можно было искать внутри файла данных.
UPDATE SECURE_TRANS SET COMMENTS = 'Transaction Comments';
UPDATE INSECURE_TRANS SET COMMENTS = 'Transaction Comments';
COMMIT;
Форсируем запись содержимого на диск, переведением табличного пространства в offline и online:
ALTER TABLESPACE SECURE1 OFFLINE;
ALTER TABLESPACE SECURE1 ONLINE;
ALTER TABLESPACE INSECURE1 OFFLINE;
ALTER TABLESPACE INSECURE1 ONLINE;
В этот момент данные из кеша записаны на диск, что произойдет, если попробовать найти их?
$ strings insecure1_01.dbf / grep Transaction
Transaction Comments
...
Эта строка обычный чистый текст в файле данных. Что будет если сделать такой же поиск по зашифрованным данным? Выполним поиск по файлу данных табличного пространства SECURE1:
$ strings secure1_01.dbf / grep Transaction
$
Ничего не вернулось, потому что файл зашифрован, и такого значения в чистом тексте нет. С этой стороны все хорошо, зашифровать получилось, но что с производительностью?
Проверим, выполнив такой запрос:
SELECT HOTEL_ID, SUM(AMT)
FROM SECURE_TRANS T, SECURE_RES R
WHERE T.RES_ID = R.RES_ID
GROUP BY HOTEL_ID;
Во время выполнения запроса включим его отладку:
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 14 0.01 0.01 4 6 0 186
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 16 0.01 0.01 4 6 0 186
Rows Row Source Operation
------- ---------------------------------------------------
186 HASH GROUP BY (cr=6 pr=4 pw=4 time=5 us cost=8 size=10400 card=200)
200 HASH JOIN (cr=6 pr=4 pw=4 time=45 us cost=7 size=10400 card=200)
200 TABLE ACCESS FULL SECURE_TRANS (cr=3 pr=2 pw=2 time=8 us cost=3 size=5200 card=200)
200 TABLE ACCESS FULL SECURE_RES (cr=3 pr=2 pw=2 time=9 us cost=3 size=5200 card=200)
Теперь выполним тот же самый запрос на таблицах INSECURE_RES и INSECURE_TRANS:
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 14 0.00 0.01 4 6 0 186
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 16 0.01 0.01 4 6 0 186
Rows Row Source Operation
------- ---------------------------------------------------
186 HASH GROUP BY (cr=6 pr=4 pw=4 time=4 us cost=8 size=10400 card=200)
200 HASH JOIN (cr=6 pr=4 pw=4 time=46 us cost=7 size=10400 card=200)
200 TABLE ACCESS FULL INSECURE_TRANS (cr=3 pr=2 pw=2 time=8 us cost=3 size=5200 card=200)
200 TABLE ACCESS FULL INSECURE_RES (cr=3 pr=2 pw=2 time=9 us cost=3 size=5200 card=200)
Обратите внимание на время выполнения запроса в обоих случаях, оно одинаковое. Использование процессора незначительное в обоих случаях. Можно сделать вывод, что шифрование не сказывается на производительности.
Представление DBA_TABLESPACES имеет новую колонку ENCRYPTED, что бы показать, зашифровано или нет табличное пространство. Дополнительное, новое представление V$ ENCRYPTED_TABLESPACES показывает тип шифрования выбранный для табличного пространства:
SQL> DESC V$ENCRYPTED_TABLESPACES
NAME NULL? TYPE
----------------------------------------- -------- ------------
TS# NUMBER
ENCRYPTIONALG VARCHAR2(7)
ENCRYPTEDTS VARCHAR2(3)
SQL> SELECT * FROM V$ENCRYPTED_TABLESPACES;
TS# ENCRYPT ENC
---------- ------- ---
5 AES128 YES
Это представление может быть объединено с колонкой TS# представления V$TABLESPACE, для получения полной картины:
SQL> DESC V$TABLESPACE
NAME NULL? TYPE
----------------------------------------- -------- ------------
TS# NUMBER
NAME VARCHAR2(30)
INCLUDED_IN_DATABASE_BACKUP VARCHAR2(3)
BIGFILE VARCHAR2(3)
FLASHBACK_ON VARCHAR2(3)
ENCRYPT_IN_BACKUP VARCHAR2(3)
Колонка ENCRYPT_IN_BACKUP не имеет ничего общего с шифрованием табличных пространств. Это касается шифрования данных RMAN, представленное в Oracle Database 10g Release 2.
Шифрование файлов Data Pump
Инструмент Data Pump представлен в Oracle 10g. И является развитием утилит IMP и EXP. Файлы Data Pump являются внешними для базы данных и содержат в себе данные, потенциально представляющие интерес злоумышленников. В целях безопасности, ранее файлы шифровались сторонними средствами.
Итак, во-первых посмотрим с какой стороны файл снимка может быть уязвим. Предположим, у вас есть таблица TRANS с колонкой COMMENTS. В ней содержится значение "Transaction Comments". Если произвести экспорт стандартно:
$ expdp scott/tiger tables=trans dumpfile=insec.dmp directory=tmp_dir
Проверим файл на наличие значения колонки:
$ strings /tmp/insec.dmp / grep Transaction
Будет выведен список найденных значений, данные в файле не зашифрованы и находятся в открытом виде.
Сейчас выполним экспорт с параметром ENCRYPTION. Так же, указывается алгоритм шифрования, в нашем случае используем алгоритм AES 128-bit.
$ expdp scott/tiger tables=trans dumpfile=sec.dmp directory=
tmp_dir encryption=data_only encryption_algorithm=aes128
Export: Release 11.1.0.7.0 - Production on Tue Nov 11 15:16:40 2008
Copyright (c) 1982, 2008, Oracle. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production on Tue Nov 11 15:16:40 2008
With the Partitioning, Oracle Label Security, OLAP, Data Mining
and Real Application Testing options
Starting "SYS"."SYS_EXPORT_TABLE_01":
'/******** AS SYSDBA' tables=scott.insecure_trans dumpfile=
sec.dmp directory=tmp_dir encryption=data_only encryption_algorithm=aes128
Estimate in progress using BLOCKS method...
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type TABLE_EXPORT/TABLE/TABLE
. . exported "SCOTT"."TRANS" 16.82 KB 200 rows
Master table "SYS"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYS.SYS_EXPORT_TABLE_01 is:
/tmp/sec.dmp
Job "SYS"."SYS_EXPORT_TABLE_01" successfully completed at 15:16:48
Проверяем полученный файл на наличие необходимой строки:
$ cat /tmp/sec.dmp / grep Transaction
$
Ничего не найдено, данные зашифрованы и недоступны в виде чистого текста.
Остается выяснить, для чего нужен ключ, и когда он используется и как дешифровать данные?
Ключ используется автоматически при работе с шифрованием, из бумажника, который был указан вами ранее. Для использования шифрования файлов Data Pump, использование шифрования табличных пространств не требуется, но требуется выполнить шаги по созданию бумажника. Так же необходимо указать, чтобы бумажник был открыт, до начала процесса шифрования и дешифрования. Если вы хорошо знаете инструментарий Data Pump, то можете указывать напрямую, через параметр ENCRYPTION_PASSWORD.
Списки доступа для UTL_TCP/HTTP/SMTP
Наверняка вам знакомы пакеты UTL_TCP, UTL_HTTP и UTL_SMTP, они отвечают за связь между серверами, за пределами базы данных. Для экземпляра, используется UTL_TCP, для установления соединения TCP/IP между двумя хостами, не через link. UTL_HTTP используется для обработки запросов Web-сервера и UTL_SMTP для обмена почтовыми сообщениями между двумя хостами.
Эти инструменты часто используются разработчиками, для обмена постовыми сообщениями через БД, отсылку какой либо информации из PL\SQL кода. И как правило, это представляет огромный риск безопасности данных.
Что бы исключить такие риски, часто забирается привилегия EXECUTE FROM PUBLIC на эти пакеты. Но, что делать, если разработчики хотят исполнять эти пакеты из вполне законного сеанса?
Oracle 11g предлагает новое решение: вы можете дать права на исполнение каждому, но контролировать, какие ресурсы исполняют эти пакеты. Например, UTL_TCP может вызываться только определенными IP-адресами. Эта возможность известна как Access Control List (ACL). Это актуально в случае, когда злоумышленник пытается использовать пакет через незаконный сеанс.
Как это работает? Первое, создаем ACL:
begin
dbms_network_acl_admin.create_acl
(
acl => 'utlpkg.xml',
description => 'Normal Access',
principal => 'CONNECT',
is_grant => TRUE,
privilege => 'connect',
start_date => null,
end_date => null
);
end;
Здесь параметр principal => 'CONNECT' показывает, что ACL обращается к роли CONNECT. Здесь можно определить пользователя или роль. ACL будет создан как файл utlpkg.xml. После создания, можно проверить, и убедится в том, что ACL добавлен:
SELECT ANY_PATH
FROM RESOURCE_VIEW
WHERE ANY_PATH LIKE '/sys/acls/%.xml';
Результат будет примерно таким:
ANY_PATH
----------------------------------------------------------------------------
/sys/acls/ANONYMOUS/ANONYMOUS3553d2be53ca40e040a8c0680777c_acl.xml
/sys/acls/OLAP_XS_ADMIN/OLAP_XS_ADMIN3551b25f93feb8dde040a8c068075b7_acl.xml
/sys/acls/OLAP_XS_ADMIN/OLAP_XS_ADMIN3551b25f944b8dde040a8c068075b7_acl.xml
/sys/acls/OLAP_XS_ADMIN/OLAP_XS_ADMIN3551b25f948b8dde040a8c068075b7_acl.xml
/sys/acls/OLAP_XS_ADMIN/OLAP_XS_ADMIN3551b25f94cb8dde040a8c068075b7_acl.xml
/sys/acls/all_all_acl.xml
/sys/acls/all_owner_acl.xml
/sys/acls/bootstrap_acl.xml
/sys/acls/ro_all_acl.xml
/sys/acls/ro_anonymous_acl.xml
/sys/acls/utlpkg.xml
Последняя строка покажет ACL созданный вами. Следующим шагом добавляем привилегии вашему ACL. На примере, ограничим пользователя SCOTT. Так же можно указать начальную и конечную даты:
begin
dbms_network_acl_admin.add_privilege
(
acl => 'utlpkg.xml',
principal => 'SCOTT',
is_grant => TRUE,
privilege => 'connect',
start_date => null,
end_date => null
);
end;
Привяжем хосты и прочие детали:
begin
dbms_network_acl_admin.assign_acl
(
acl => 'utlpkg.xml',
host => 'www.all-oracle.ru',
lower_port => 22,
upper_port => 55
);
end;
Здесь определили, что пользователь SCOTT может работать с хоста all-oracle.ru, по портам с 22 по 55, и не извне.
SQL> GRANT EXECUTE ON UTL_HTTP TO scott;
Grant succeeded.
SQL> CONN scott/tiger
Connected.
SQL> SELECT UTL_HTTP.REQUEST('http://www.all-oracle.ru') FROM DUAL;
SELECT UTL_HTTP.REQUEST('http://www.all-oracle.ru') FROM DUAL
*
ERROR at line 1:
ORA-29273: HTTP request failed
ORA-06512: at "SYS.UTL_HTTP", line 1577
ORA-24247: network access denied by access control list (ACL)
ORA-06512: at line 1
Обратим внимание, сообщение об ошибке ORA-24247: network access denied by access control list (ACL). Пользователь вызвал web-сервер по 80 порту, который не входит в диапазон портов от 22 до 55. Таким образом, предотвращены потенциально опасные действия пользователя.
Добавим еще правила, для разрешения соединения:
begin
dbms_network_acl_admin.assign_acl
(
acl => 'utlpkg.xml',
host => 'www.all-oracle.ru',
lower_port => 1,
upper_port => 10000
);
end;
PL/SQL procedure successfully completed.
SQL> CONN scott/tiger
Connected.
SQL> SELECT UTL_HTTP.REQUEST('http://www.all-oracle.ru') FROM DUAL;
UTL_HTTP.REQUEST('HTTP://WWW.ALL-ORACLE.RU')
--------------------------------------------------------------------------------
<!--CTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//E-->...
Но это работает только для www.all-oracle.ru, и ни для чего более. Если вы выберите какой либо другой сайт, то снова получите ошибку ORA-24247. В итоге получаем достаточно гибкую систему защиты.
Для получения информации о ACL выполните запрос к представлению DBA_NETWORK_ACLS:
SELECT HOST, LOWER_PORT, UPPER_PORT, ACL, ACLID
FROM DBA_NETWORK_ACLS
WHERE ACL='/sys/acls/utlpkg.xml';
Маскирование данных
Во многих организациях, использующих QA базы данных, время от времени обновляют данные из промышленной базы данных, помогая разработчикам исполнять пре-релизы кода на актуальных данных прежде, чем помещать их на продуктивную базу данных.
Несмотря на это, это может быть проблемой в плане безопасности - когда данные из промышленной базы данных обновляются важные данные, возможны риски при переносе данных. Чтобы отловить эти риски, многие организации обновляют важные данные на какие-то менее важные значения в "тестовой" БД, на практике называемые "маскировка данных". Например, вы можете хотеть обновить SSN(ИНН) используя случайные 9-значные цифровые строки, чтобы скрыть реальные данные.
В Oracle 11g Data Pump имеет новый параметр remap_data, для подмены данных во время импорта.
Первым делом создаем функцию remap:
create or REPLACE package pkg_mask
as
function fn_mask_ssn (p_in VARCHAR2) return VARCHAR2;
end;
/
create or REPLACE package body pkg_mask
as
function fn_mask_ssn (p_in VARCHAR2)
return VARCHAR2
is
begin
return LPAD (
ROUND(dbms_random.value (001000000,999999999)),
9,0);
end;
end;
Эта функция получает аргумент VARCHAR, и возвращает 9 символов. Используем эту функцию для маскировки SSN (ИНН). Ниже показано как выглядит таблица ACCOUNTS:
SQL> SELECT * FROM ACCOUNTS;
ACC_NO ACC_NAME ACC_SSN
---------- ------------------------------ ---------
1 John Smith 123456789
2 Jane Doe 234567890
Вы хотите замаскировать колонку ACC_SNN. Экспортируем таблицу используя утилиту Data Pump. Во время экспорта используется параметр remap_data, для маскировки данных в экспортном файле:
$ expdp scott/tiger tables=scott.accounts dumpfile=
accounts.dmp directory=tmp_dir remap_data=accounts.acc_ssn:pkg_mask.fn_mask_ssn
Параметр помещает значение генерируемое функцией fn_mask_ssn в пакете pkg_mask. Шаблн выглядит так:
[<имя_схемы>.]<имя_таблицы>.<имя_колонки>:[<имя_схемы>.]<имя_пакета>.<имя_функции>
Имя_колонки - имя колонки данные которой вы хотите замаскировать. Основная логика находится в <имя_пакета>.<имя_функции>. Теперь вы можете импортировать таблицу в тестовую базу данных. После импорта проверяем данные в таблице:
SQL> SELECT * FROM ACCOUNTS;
ACC_NO ACC_NAME ACC_SSN
---------- ------------------------------ ---------
1 John Smith 645270861
2 Jane Doe 538996590
Значения отличаются от начального варианта, они сгенерированы функцией fn_mask_ssn из пакета pkg_mask. При импорте, будут импортированы эти значения.
Если у вас есть экспортированная таблица без параметра remap_data, то данные в ней верные. И при импорте вы можете их маскировать, используя тот же параметр:
$ impdp scott/tiger dumpfile=accounts.dmp remap_data=
accounts.acc_ssn:pkg_mask.fn_mask_ssn directory=tmp_dir tables=accounts
Здесь будем использовать функцию, генерирующую случайные значения. Например, требование, заменить все цифры SSN (ИНН), за исключением последних четырех, знаками X:
create or REPLACE package pkg_mask
as
function fn_mask_ssn (p_in VARCHAR2) return VARCHAR2;
end;
/
create or REPLACE package body pkg_mask
as
function fn_mask_ssn (p_in VARCHAR2)
return VARCHAR2
is
begin
return 'XXXXX'// SUBSTR (p_in,6,4);
end;
end;
Эти функции можно применить практически к каждой колонке, и использование этой возможности имеет широкий спектр.
Примечание
В предыдущих версиях большинство операций безопасности выполнялись средствами инструмента Oracle Security Manager. В Oracle 11g Oracle Enterprise Manager содержит все необходимые инструменты для выполнения этих действий.