005-安全

2dd87c57926faa5f68806880d5b56801
2de413935ff32ca6ecad7d1c41db72cf

透明数据加密技术(TDE)

TDE - 基于列的加密

Oracle TDE的全称是Transparent Data Encryption 透明数据加密。它的优点是对应用透明,管理简便,无需应用设置,但它也有如下限制:

  1. 只能使用B-Tree索引
  2. 加密的列无法对索引进行rang scan操作。
  3. 外部对象
  4. 可传输表空间
  5. exp/imp操作

由于有了Oracle的TDE-基于列的加密,你所要做的只是定义需要加密的列,Oracle将为包含加密列的表创建一个私密的安全加密密钥,然后采用你指定的加密算法加密指定列的明文数据。
TDE支持的加密算法有:3DES168 、AES128、AES192、AES256
1)保证数据库兼容版本高于10gr2,查看数据库版本

1
show parameter compatible

2)设定wallet的位置(在sqlnet.ora文件中写入如下内容,需要重启数据库才能生效):

1
2
3
4
5
ENCRYPTION_WALLET_LOCATION =
(SOURCE=
(METHOD=file)
(METHOD_DATA=
(DIRECTORY=C:\app\xianzhu\product\11.2.0\wallet)))

3)在wallet里面创建key,以下命令将会在对应目录下产生wallet

1
alter system set encryption key authenticated by "myPassword";

4)创建一个表,对其中某列加密

1
2
3
4
5
--创建表
create table tde_private(id number(10),
info varchar2(50) encrypt using 'AES192');
--查询加密列
select * from dba_encrypted_columns;

5)如果关闭wallet,无法访问加密的数据

1
2
3
4
5
6
--关闭/打开wallet
alter system set wallet close/open identified by "myPassword";
--关闭时如果进行查询会报错
select * from tde_private;
第 1 行出现错误:
ORA-28365: Wallet 未打开

TDE - 基于表空间的加密

这是Oracle 11g推出的新特性,它是对整个表空间进行加密。
下面是创建一个加密表空间的语句:

1
2
3
4
5
6
7
create tablespace encrypted_ts encryption using 'AES256' default storage(encrypt);

select tablespace_name,encrypted from dba_tablespaces where tablespace_name='ENCRYPTED_TS';

TABLESPACE_NAME ENC
------------------------------ ---
ENCRYPTED_TS YES

加密字段 VS 加密表空间

表空间加密 是放生在数据存储的时候,也就是存储在文件上的数据已经被加密;字段加密发生在SQL层,由SQL调用一个算法对数据进行加密处理。
表空间加密的数据,不会再受到字段加密的限制,比如:

  1. 字段类型
  2. 索引类型
  3. 需要 no salt常见索引

加密表空间的限制:

  1. 外部大对象(bfiles)不可以
  2. exp/imp不行,需要用expdp/impdp

    虚拟私有数据库 (VPD)

    VPD的全称是Virtual Private Database 虚拟私有数据库,它在Oracle 8i时就出现了,是Oracle比较早期的一种数据安全手段。
    它是指通过指定策略,对用户的SQL自动添加过滤谓词,以达到对结果集进行过滤的目的,其示意图如下:
    9432167d49c2dcf9df2038e6320dccaf
    其大致过程如下:用户发出SQL语句访问表中数据,此时触发定义在该表上的安全策略,该安全策略会在相应的列上加上Where谓词条件,最终返回给用户的是过滤后的结果集。这样用户只能看到自己有权限看到的数据,其效果如下图所示:
    0bab4f6d6c49e7e3131c40a20b156d84
    用户1和用户2虽然发出了两个一模一样的SQL语句,但根据相应的安全策略,他们得到的结果有可能不一样,就像访问自己私有的数据库一样,这也是为什么这项技术叫虚拟私有数据库。
    1)创建一个函数,该函数定义要加哪些谓词条件:
    1
    2
    3
    4
    5
    create or replace function hide_sal_comm(v_schema varchar2, v_object varchar2) return varchar2 as con varchar2(200);
    begin
    con:='deptno=30';
    return(con);
    end hide_sal_comm;

2)利用dmbs_rls.add_policy()添加一个安全策略

1
2
3
4
5
6
7
 begin
dbms_rls.add_policy(object_schema => 'scott', --指定schema
object_name => 'emp', --指定表
policy_name => 'hide_sal_policy', --自定义此安全策略名称
policy_function => 'hide_sal_comm', --指定函数
sec_relevant_cols => 'sal,comm'); --指定过滤的字段
end;

3)添加安全策略后访问该表,发现只能获得deptno=30的数据。这里要注意的是,只有当访问安全策略中指定字段时才起作用,如果select的字段中不包含这些字段,安全策略是不会起作用的

1
2
select * from scott.emp;              --起作用
select ename,deptno from scott.emp; --不起作用,因为查询字段不包含sal或comm

4)上面定义的安全策略有个缺点,就是会把所有的字段都隐藏,如果你只想隐藏敏感字段,可以如下设置:

1
2
3
4
5
6
7
8
9
10
11
--删除上面建的安全策略
exec dbms_rls.drop_policy('scott','emp','hide_sal_policy');
--
Begin
dbms_rls.add_policy(object_schema => 'scott',
object_name => 'emp',
policy_name => 'hide_sal_policy',
policy_function => 'hide_sal_comm',
sec_relevant_cols => 'sal,comm',
sec_relevant_cols_opt => dbms_rls.ALL_ROWS);
end;

5)这时再执行同样的语句,可以发现返回所有行,只是敏感字段的数据被隐藏了

Vault

和VPD,OLS不不一样的是,Vault在实际的生产环境下,最主要的目的是为了防止具有sys账户DBA滥用权限。在没有vault情况下,DBA可以随意查看数据,这对于一些企业(特别是金融领域)来说是不允许的,而有了Vault,就可以控制DBA不能访问应用的核心数据,如下图所示:
be429d2071c4020234504026fa5a84cf

审计Audit

Oracle的审计是一个事后的工作,即数据库出现安全问题后,为了定位、发现问题的根源,可以通过审计追根溯源。Oracle审计主要包含以下3个部分:

  1. Trigger-based Auditing(触发器)
  2. Auditing the sys User-(SYS用户审计)
  3. Standard Auditing (标准审计)

    触发器审计

    下面是一个触发器审计的例子,一旦emp表的sal字段的值增大超过1.1倍,就在审计表emp_sal_audit里记录该次操作。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TRIGGER trg_a_idu_r_emp_sal 
    AFTER INSERT OR DELETE OR UPDATE OF sal ON emp
    FOR EACH ROW
    BEGIN
    IF ( :NEW.sal > :OLD.sal * 1.10 ) THEN
    INSERT INTO emp_sal_audit
    VALUES (:OLD.empno,
    :OLD.sal,
    :NEW.sal,
    USER,
    SYSDATE);
    END IF;
    END;

SYS用户的审计

对SYS用户的审计比较特殊,因为SYS用户的权限太大,它的审计信息不能存储在数据库里,否则SYS可以随意修改审计信息,因此sys用户审计日志写到操作系统日志中。
下面是一个例子:
1)首先启动对SYS用户的审计

1
alter system set audit_sys_operations = true scope = spfile;

2)用SYS用户向测试表插入一条数据

1
insert into test.t (object_id) values(1);

3)在操作系统日志中可以看到如下信息

1
Audit trail: LENGTH : '176' ACTION :[7] 'CONNECT' DATABASE USER:[1] '/' PRIVILEGE :[6] 'SYSDBA' CLIENT USER:[12] 'CORP\xianzhu' CLIENT TERMINAL:[14] 'L-SHC-00436132' STATUS:[1] '0' DBID:[10] '1327298419' .

标准审计

标准审计根据对象不同,可以分为以下4个部分:

  1. 审计会话
  2. 审计对象
  3. 审计操作
  4. 审计授权

1)首先,开启标准审计

1
2
3
4
--开启标准审计
ALTER SYSTEM SET AUDIT_TRAIL = DB,EXTENDED SCOPE = SPFILE;
--设置审计的表
audit select, insert, update, delete on test.t;

2)在表上做DML操作,可以在审计表里查看相应审计信息

1
2
3
4
5
6
7
8
9
col userid for a10
col obj$name for a10
col sqltext for a40
select userid,obj$name,sqltext from sys.aud$ where userid='TEST' and obj$name='T';

USERID OBJ$NAME SQLTEXT
---------- ---------- ----------------------------------------
TEST T delete from test.t
TEST T insert into t (object_id) values(1)