<b>经验之谈:利用Oracle的TDE特点加密-备份恢复</b>[Oracle防范]
本文“<b>经验之谈:利用Oracle的TDE特点加密-备份恢复</b>[Oracle防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
利用作为 Oracle 高级安全选件(版本 10.2 及更高版本)的一部份引入的 Oracle 数据库透明数据加密 (TDE),可以有挑选地对保存在数据库底层数据文件中的敏感数据库数据以及全部下游文件组件(如联机重做日记、归档重做日记和数据库备份)举行加密.TDE 的基本目标是保护在这些原始操作系统文件中发现的敏感数据,避免不怀好意的人拜候磁盘或备份磁带时对这些数据举行窥测,然后尝试复原数据库或扫描原始操作系统文件中的数据,如个人可辨认信息或信誉卡信息.
作为我的咨询惯例的一部份,我已经实施 TDE 多次.但是,在此中一个近来的合约之前,我一向利用 TDE 对现有表中的新列或属于全新表的摆列行加密.在这两种情形下利用 TDE 非常简单,因为目标列为空,因此由于贫乏数据和现有利用程序相关性而不会触及较大的风险.
我近来实施 TDE 的体验有所差别.我帮忙一家大型公司对一个已超越一百万行的表中的现有摆列行加密.还有一个依靠于列的关键任务利用程序,因此,您可以假想一下,在开始工作之前有很多重要的事情要考虑.在 Internet 上搜索可供应经验的近似情形之后,我发现只有几个优异的资源可以帮忙我.
本文概述了我在通过利用 TDE 对现有数据举行加密的历程中总结出的经验教导.假如您尝试对现有列数据利用 TDE,我但愿此处供应的信息可帮忙您疾速有效地展开近似工作.
肯定大概的限制
研究客户的系统时,我做的第一件事情就是查找与目标列有关的将禁止我们对列加密的数据模子特点,大概查找大概对现有操作产生负面影响的有关列的事项.该研究包含查找列索引和完好性约束.
正如 Oracle 文档明确声明,当您想对具有索引的某个摆列行加密时,需求理解很多限制条件.Oracle 不答应对具有位图索引的摆列行加密,这与我们的情形没有密切关系.但是,目标列具有多个普通的(B 树)索引.固然 Oracle 答应对具有普通索引的摆列行加密,但是 Oracle 禁止对索引摆列行"salt 处理"加密.Salt 处理通过在加密之前向数据增添随机字符串来提高反复数据的安全性,因此窃贼利用情势匹配辨认技术越发难于破解加密的数据.总而言之,经过这个最初的解析之后,我们会碰到一种情形,那就是我们可以对摆列行加密,但不能举行 salt 处理.
对列索引举行解析后,我本可以到此为止,但是我想答复的下一个问题是"利用这些索引符合吗?"我的考虑历程是这样:假如索引没有效,那么我会将其删除,从而削减保护索引条目所必须的系统开销,特别是考虑到加密的额外负担.要判断索引能否有效,我利用 Oracle 数据库的索引监督特点.我发现,实际上索引正处于利用当中,因此我们必须对其持续举行保护.
接下来,我查看了引用完好性约束条件中能否触及目标列.由于每个表都具有其自己的加密密钥,因此 Oracle 不答应您利用 TDE 对外键关系中触及的摆列行加密.在我们的情形下,引用完好性约束条件中未触及目标列.
评价性能开销
我的客户询问的第一组问题之一就是"TDE 对我的利用程序的普通性能影响若何?"Oracle 文档中有一小部份阐述了普通情形下 TDE 对相关利用程序性能的影响.但是我的客户但愿得到一些具体的统计信息,以帮忙他们理解 TDE 若何影响平常举行的有严峻时间要求的数据加载历程.
为了满意客户需求,我计算了每天在有严峻时间要求的历程中插入到目标表中的平均行数.然后,我在客户端的相同沙箱环境中成立了一个近似的测试表和索引,丈量在加密目标列前后插入相同数目的行所耗费的时间.时间损耗上的差别让我们更好地理解了在该历程中对列数据举行加密所造成的"性能丧失".列表 1 是我若何利用 SQL*Plus 履行该操作的示例.
SQL> CONNECT system
Enter password:
Connected.
SQL> -- Configure Oracle-Managed (Data) Files
SQL> ALTER SYSTEM
2 SET db_create_file_dest = '/data01/oracle/'
3 SCOPE = MEMORY;
System altered.
SQL> -- Create two new tablespaces for the demo,
SQL> -- one for data segments, one for index segments
SQL> CREATE TABLESPACE data_001
2 DATAFILE SIZE 1G;
Tablespace created.
SQL> CREATE TABLESPACE indx_001
2 DATAFILE SIZE 500M;
Tablespace created.
SQL> -- Create a user for the demo
SQL> CREATE USER app_001 IDENTIFIED BY app
2 DEFAULT TABLESPACE data_001
3 TEMPORARY TABLESPACE temp
4 QUOTA UNLIMITED ON data_001
5 QUOTA UNLIMITED ON indx_001;
User created.
SQL> GRANT CREATE SESSION, CREATE TABLE TO app_001;
Grant succeeded.
SQL> -- Work as the demo user
SQL> CONNECT app_001/app;
Connected.
SQL> -- Create the demo table in the default tablespace
SQL> CREATE TABLE app_001.transactions (
2 trans_id INTEGER
3 CONSTRAINT transactions_pk PRIMARY KEY
4 USING INDEX TABLESPACE indx_001,
5 credit_card INTEGER NOT NULL
6 );
Table created.
SQL> -- Create an index in the INDX_001 tablespace
SQL> CREATE INDEX app_001.transactions_ndx1
2 ON app_001.transactions(credit_card)
3 TABLESPACE indx_001;
Index created.
SQL> -- Time how long it takes to load data in the clear
SQL> SET TIMING ON;
SQL> BEGIN
2 -- AMEX
3 FOR i IN 1 .. 100000 LOOP
4 INSERT INTO app_001.transactions(trans_id, credit_card)
5 VALUES (
6 i,
7 '34' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
8 );
9 END LOOP;
10 COMMIT;
11 -- VISA
12 FOR i IN 100001 .. 400000 LOOP
13 INSERT INTO app_001.transactions(trans_id, credit_card)
14 VALUES (
15 i,
16 '4' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>999999999999999))
17 );
18 END LOOP;
19 COMMIT;
20 -- MASTERCARD
21 FOR i IN 400001 .. 500000 LOOP
22 INSERT INTO app_001.transactions(trans_id, credit_card)
23 VALUES (
24 i,
25 '54' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
26 );
27 END LOOP;
28 COMMIT;
29 END;
30 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:56.14
SQL> SET TIMING OFF;
SQL> -- Remove existing synthetic data
SQL> TRUNCATE TABLE app_001.transactions;
Table truncated.
SQL> -- Enable encryption of the credit card column
SQL> ALTER TABLE app_001.transactions
2 MODIFY (credit_card ENCRYPT NO SALT);
Table altered.
SQL> -- Time how long it takes to load encrypted data
SQL> SET TIMING ON;
SQL> BEGIN
2 -- AMEX
3 FOR i IN 1 .. 100000 LOOP
4 INSERT INTO app_001.transactions(trans_id, credit_card)
5 VALUES (
6 i,
7 '34' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
8 );
9 END LOOP;
10 COMMIT;
11 -- VISA
12 FOR i IN 100001 .. 400000 LOOP
13 INSERT INTO app_001.transactions(trans_id, credit_card)
14 VALUES (
15 i,
16 '4' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>999999999999999))
17 );
18 END LOOP;
19 COMMIT;
20 -- MASTERCARD
21 FOR i IN 400001 .. 500000 LOOP
22 INSERT INTO app_001.transactions(trans_id, credit_card)
23 VALUES (
24 i,
25 '54' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
26 );
27 END LOOP;
28 COMMIT;
29 END;
30 /
PL/SQL procedure successfully completed.
Elapsed: 00:01:16.31
SQL> SET TIMING OFF;
列表 1 利用与您的生产环境相同的沙箱环境,简单对比启用列加密前后加载代表性数据集所耗费的时间,以使您更好地理解列加密对生产系统性能的影响.
和全部的性能测试一样,我猜疑对摆列行加密所造成的性能丧失会因系统而异,具体取决于普通变量(CPU、平均负载等).在列表 1 中,您注意到计算的性能丧失为 36% (((56.14-76.31)/56.14)*100),但是,利用我们在客户系统中汇集的实行证据,预计数据加载历程所耗费的时间应当大约增添 11%,这与在生产中利用 TDE 得到后果完好一样.
在本例中,我侧重于对具有索引的数据加载历程预计数据加密的性能丧失.假如您的系统具有差别范例的关键历程,如要求尖刻的报表生成周期,那么我倡议您利用沙箱环境来对比数据加密前后该历程所耗费的时间.本文背面的"肯定潜在查询筹划更改"部份将谈论查询和数据加密的分外注意事项.
处理停机和保护时间
我的客户对比关心的另一个问题是,在加密约一百万行的表中的现有列数据时,需求对哪些生产利用程序(假若有)举行必要的停用.我最初设法是,理论上不需求终止任何利用程序 — 毕竟,Oracle 文档明确表示了对现有列的数据举行加密本质上就是对整个表举行多行更新.假如没有更多地考虑这件事,我不会懂得为什么新行无法并发插入到表中以及为什么现有行更新无法持续.当我咕哝着熟习的 Oracle 口号"读取方不会禁止写入方,写入方也不会禁止读取方"时,我的确没有想到列加密会影响查询.
但是,在长时间从事 DBA 工作后,我才总结出,若要对生产系统举行终究的实际更改,需求对理论举行测试,以避免呈现不测问题,这一点非常重要.您瞧,当我在加密列期间,针对沙箱数据库对利用程序本身举行了测试,从而发现了很多问题.最重要的是,我发现举行中的加密延伸了某些查询的呼应时间,以至于利用程序会碰到呼应超时.这些超时又会造成衔接断开,然后招致后续的事件失利,进而会越发麻烦 — 我将为您供应具体信息.
必须一提的是,测试之后,我理解到终止利用程序运行绝对不是没有来由的.但下一个问题是,生产利用程序需求脱机多久?在筹划每个周末举行的正常两小时的保护时间之内可以对摆列行加密吗?大概,需求更长的停机时间?为了弄清这个问题,我只需丈量在沙箱环境中对摆列行加密所耗费的时间,因为沙箱环境与生产环境具有相同的服务器硬件和数据集.我发现,列加密要耗费一个小时多一点的时间才能完成.率直地说,由于我利用近似数据在笔记本电脑上模拟测试加密运行才耗费了不到 5 分钟的时间,因此关于它耗费这么长时间,我感到非常震惊.但是当我们在生产数据库系统中对摆列行加密时,最要紧的是要利用陈旧服务器硬件所发生的情形.
理解到在正常保护时间内履行其他任务需求更多时间,我决意必须找到削减加密列耗费时间的办法.我的第一个直觉就是删除包含目标列的两个索引.这样,Oracle 只需加密表本身中的列数据,之后我可以有效地重建索引,而没有日记记录开销.经过一些新的测试之后,我将加密列以及相关索引所需的时间从 70 分钟(在加密期间存在索引)削减到仅 20 分钟(加密列后重建索引).列表 2 是我用来得出结论的测试示例(从我们在列表 1 中终止的位置持续).此外,请注意,列表中的时间来自用来编写本文的测试系统,而不是来自我的客户端利用的实际系统.
SQL> -- Remove existing synthetic data
SQL> TRUNCATE TABLE app_001.transactions;
Table truncated.
SQL> -- Disable encryption of the credit card column
SQL> ALTER TABLE app_001.transactions
2 MODIFY (credit_card DECRYPT);
Table altered.
SQL> -- Load new synthetic data
SQL> BEGIN
2 -- AMEX
3 FOR i IN 1 .. 100000 LOOP
4 INSERT INTO app_001.transactions(trans_id, credit_card)
5 VALUES (
6 i,
7 '34' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
8 );
9 END LOOP;
10 COMMIT;
11 -- VISA
12 FOR i IN 100001 .. 400000 LOOP
13 INSERT INTO app_001.transactions(trans_id, credit_card)
14 VALUES (
15 i,
16 '4' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>999999999999999))
17 );
18 END LOOP;
19 COMMIT;
20 -- MASTERCARD
21 FOR i IN 400001 .. 500000 LOOP
22 INSERT INTO app_001.transactions(trans_id, credit_card)
23 VALUES (
24 i,
25 '54' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
26 );
27 END LOOP;
28 COMMIT;
29 END;
30 /
PL/SQL procedure successfully completed.
SQL> -- Time how long it takes to encrypt credit card data
SQL> -- with corresponding indexes in place
SQL> SET TIMING ON;
SQL> ALTER TABLE app_001.transactions
2 MODIFY (credit_card ENCRYPT NO SALT);
Table altered.
Elapsed: 00:02:27.18
SQL> SET TIMING OFF;
SQL> -- Remove existing synthetic data
SQL> TRUNCATE TABLE app_001.transactions;
Table truncated.
SQL> -- Drop all indexes that correspond to the credit card column
SQL> DROP INDEX app_001.transactions_ndx1;
Index dropped.
SQL> -- Disable encryption of the credit card column
SQL> ALTER TABLE app_001.transactions
2 MODIFY (credit_card DECRYPT);
Table altered.
SQL> -- Load new synthetic data
SQL> BEGIN
2 -- AMEX
3 FOR i IN 1 .. 100000 LOOP
4 INSERT INTO app_001.transactions(trans_id, credit_card)
5 VALUES (
6 i,
7 '34' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
8 );
9 END LOOP;
10 COMMIT;
11 -- VISA
12 FOR i IN 100001 .. 400000 LOOP
13 INSERT INTO app_001.transactions(trans_id, credit_card)
14 VALUES (
15 i,
16 '4' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>999999999999999))
17 );
18 END LOOP;
19 COMMIT;
20 -- MASTERCARD
21 FOR i IN 400001 .. 500000 LOOP
22 INSERT INTO app_001.transactions(trans_id, credit_card)
23 VALUES (
24 i,
25 '54' || TRUNC(DBMS_RANDOM.VALUE(low=>0, high=>99999999999999))
26 );
27 END LOOP;
28 COMMIT;
29 END;
30 /
PL/SQL procedure successfully completed.
SQL> -- Time how long it takes to:
SQL> -- 1. Encrypt credit card data without corresponding indexes in place
SQL> -- 2. Recreate corresponding indexes
SQL> SET TIMING ON;
SQL> ALTER TABLE app_001.transactions
2 MODIFY (credit_card ENCRYPT NO SALT);
Table altered.
Elapsed: 00:01:15.48
SQL> CREATE INDEX app_001.transactions_ndx1
2 ON app_001.transactions(credit_card)
3 TABLESPACE indx_001
4 PARALLEL 2
5 NOLOGGING;
Index created.
Elapsed: 00:00:02.98
SQL> SET TIMING OFF;
列表 2 要快速履行对现有数据举行加密的历程,只需在对其举行加密之前删除列的底层索引,然后再重建索引.
注:本文的模拟环境中利用了 CREATE INDEX 语句.在实际的设置中,可考虑利用 Oracle 数据库的 DBMS_METADATA 实用程序包来生成 CREATE INDEX 语句,您可以利用这些语句在完成数据加密之后重新成立索引.
总之,在列加密之后重建索引的新战略可留出更多时间来处理整个历程中最具挑衅性的问题,这将在下一部份中举行阐明.
以上是“<b>经验之谈:利用Oracle的TDE特点加密-备份恢复</b>[Oracle防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |