亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

經(jīng)驗(yàn)之談:使用Oracle的TDE特性加密

瀏覽:8日期:2023-11-29 14:01:34

使用作為 Oracle高級(jí)安全選件(版本 10.2 及更高版本)的一部分引入的 Oracle數(shù)據(jù)庫透明數(shù)據(jù)加密 (TDE),可以有選擇地對(duì)保留在數(shù)據(jù)庫底層數(shù)據(jù)文件中的敏感數(shù)據(jù)庫數(shù)據(jù)以及所有下游文件組件(如聯(lián)機(jī)重做日志、歸檔重做日志和數(shù)據(jù)庫備份)進(jìn)行加密。TDE 的基本目標(biāo)是保護(hù)在這些原始操作系統(tǒng)文件中發(fā)現(xiàn)的敏感數(shù)據(jù),防止不懷好意的人訪問磁盤或備份磁帶時(shí)對(duì)這些數(shù)據(jù)進(jìn)行窺探,然后嘗試還原數(shù)據(jù)庫或掃描原始操作系統(tǒng)文件中的數(shù)據(jù),如個(gè)人可識(shí)別信息或信用卡信息。

作為我的咨詢慣例的一部分,我已經(jīng)實(shí)施 TDE 多次。但是,在其中一個(gè)最近的合約之前,我一直使用 TDE 對(duì)現(xiàn)有表中的新列或?qū)儆谌卤淼牧羞M(jìn)行加密。在這兩種情況下使用 TDE 非常簡(jiǎn)單,因?yàn)槟繕?biāo)列為空,因此由于缺乏數(shù)據(jù)和現(xiàn)有應(yīng)用程序相關(guān)性而不會(huì)涉及較大的風(fēng)險(xiǎn)。

我最近實(shí)施 TDE 的體驗(yàn)有所不同。我?guī)椭患掖笮凸緦?duì)一個(gè)已超過一百萬行的表中的現(xiàn)有列進(jìn)行加密。還有一個(gè)依賴于列的關(guān)鍵任務(wù)應(yīng)用程序,因此,您可以設(shè)想一下,在開始工作之前有很多重要的事情要考慮。在 Internet 上搜索可提供經(jīng)驗(yàn)的類似情形之后,我發(fā)現(xiàn)只有幾個(gè)優(yōu)秀的資源可以幫助我。

本文概述了我在通過使用 TDE 對(duì)現(xiàn)有數(shù)據(jù)進(jìn)行加密的過程中總結(jié)出的經(jīng)驗(yàn)教訓(xùn)。如果您嘗試對(duì)現(xiàn)有列數(shù)據(jù)使用 TDE,我希望此處提供的信息可幫助您迅速有效地開展類似工作。

確定可能的限制

研究客戶的系統(tǒng)時(shí),我做的第一件事情就是查找與目標(biāo)列有關(guān)的將禁止我們對(duì)列加密的數(shù)據(jù)模型特征,或者查找可能對(duì)現(xiàn)有操作產(chǎn)生負(fù)面影響的有關(guān)列的事項(xiàng)。該研究包括查找列索引和完整性約束。

正如 Oracle 文檔明確聲明,當(dāng)您想對(duì)具有索引的某個(gè)列進(jìn)行加密時(shí),需要了解很多限制條件。Oracle 不允許對(duì)具有位圖索引的列進(jìn)行加密,這與我們的情況沒有密切關(guān)系。但是,目標(biāo)列具有多個(gè)普通的(B 樹)索引。盡管 Oracle 允許對(duì)具有普通索引的列進(jìn)行加密,但是 Oracle 禁止對(duì)索引列進(jìn)行“salt 處理”加密。Salt 處理通過在加密之前向數(shù)據(jù)添加隨機(jī)字符串來提高重復(fù)數(shù)據(jù)的安全性,因此竊賊使用模式匹配識(shí)別技術(shù)更加難于破解加密的數(shù)據(jù)??偠灾?,經(jīng)過這個(gè)最初的分析之后,我們會(huì)遇到一種情況,那就是我們可以對(duì)列進(jìn)行加密,但不能進(jìn)行 salt 處理。

對(duì)列索引進(jìn)行分析后,我本可以到此為止,但是我想回答的下一個(gè)問題是“使用這些索引合適嗎?”我的思考過程是這樣:如果索引沒有用,那么我會(huì)將其刪除,從而減少維護(hù)索引條目所必需的系統(tǒng)開銷,尤其是考慮到加密的額外負(fù)擔(dān)。要判斷索引是否有用,我使用 Oracle 數(shù)據(jù)庫的索引監(jiān)視特性。我發(fā)現(xiàn),實(shí)際上索引正處于使用當(dāng)中,因此我們必須對(duì)其繼續(xù)進(jìn)行維護(hù)。

接下來,我查看了引用完整性約束條件中是否涉及目標(biāo)列。由于每個(gè)表都具有其自己的加密密鑰,因此 Oracle 不允許您使用 TDE 對(duì)外鍵關(guān)系中涉及的列進(jìn)行加密。在我們的情況下,引用完整性約束條件中未涉及目標(biāo)列。

評(píng)估性能開銷

我的客戶詢問的第一組問題之一就是“TDE 對(duì)我的應(yīng)用程序的一般性能影響如何?”O(jiān)racle 文檔中有一小部分論述了一般情況下 TDE 對(duì)相關(guān)應(yīng)用程序性能的影響。但是我的客戶希望獲得一些具體的統(tǒng)計(jì)信息,以幫助他們了解 TDE 如何影響日常進(jìn)行的有嚴(yán)格時(shí)間要求的數(shù)據(jù)加載過程。

為了滿足客戶需求,我計(jì)算了每天在有嚴(yán)格時(shí)間要求的過程中插入到目標(biāo)表中的平均行數(shù)。然后,我在客戶端的相同沙箱環(huán)境中創(chuàng)建了一個(gè)類似的測(cè)試表和索引,測(cè)量在加密目標(biāo)列前后插入相同數(shù)量的行所花費(fèi)的時(shí)間。時(shí)間消耗上的差別讓我們更好地了解了在該過程中對(duì)列數(shù)據(jù)進(jìn)行加密所造成的“性能損失”。列表 1 是我如何使用 SQL*Plus 執(zhí)行該操作的示例。

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使用與您的生產(chǎn)環(huán)境相同的沙箱環(huán)境,簡(jiǎn)單比較啟用列加密前后加載代表性數(shù)據(jù)集所花費(fèi)的時(shí)間,以使您更好地了解列加密對(duì)生產(chǎn)系統(tǒng)性能的影響。

和所有的性能測(cè)試一樣,我懷疑對(duì)列進(jìn)行加密所造成的性能損失會(huì)因系統(tǒng)而異,具體取決于普通變量(CPU、平均負(fù)載等)。在列表 1 中,您注意到計(jì)算的性能損失為 36% (((56.14-76.31)/56.14)*100),但是,使用我們?cè)诳蛻粝到y(tǒng)中收集的實(shí)驗(yàn)證據(jù),預(yù)計(jì)數(shù)據(jù)加載過程所耗費(fèi)的時(shí)間應(yīng)該大約增加 11%,這與在生產(chǎn)中使用 TDE 獲得結(jié)果完全一樣。

在本例中,我側(cè)重于對(duì)具有索引的數(shù)據(jù)加載過程估計(jì)數(shù)據(jù)加密的性能損失。如果您的系統(tǒng)具有不同類型的關(guān)鍵過程,如要求苛刻的報(bào)表生成周期,那么我建議您使用沙箱環(huán)境來比較數(shù)據(jù)加密前后該過程所花費(fèi)的時(shí)間。本文后面的“確定潛在查詢計(jì)劃更改”部分將討論查詢和數(shù)據(jù)加密的特別注意事項(xiàng)。

處理停機(jī)和維護(hù)時(shí)間

我的客戶比較關(guān)心的另一個(gè)問題是,在加密約一百萬行的表中的現(xiàn)有列數(shù)據(jù)時(shí),需要對(duì)哪些生產(chǎn)應(yīng)用程序(如果有)進(jìn)行必要的停用。我最初想法是,理論上不需要停止任何應(yīng)用程序 — 畢竟,Oracle 文檔明確表示了對(duì)現(xiàn)有列的數(shù)據(jù)進(jìn)行加密本質(zhì)上就是對(duì)整個(gè)表進(jìn)行多行更新。如果沒有更多地考慮這件事,我不會(huì)明白為什么新行無法并發(fā)插入到表中以及為什么現(xiàn)有行更新無法繼續(xù)。當(dāng)我咕噥著熟悉的 Oracle 口號(hào)“讀取方不會(huì)阻止寫入方,寫入方也不會(huì)阻止讀取方”時(shí),我的確沒有想到列加密會(huì)影響查詢。

但是,在長(zhǎng)時(shí)間從事 DBA 工作后,我才總結(jié)出,若要對(duì)生產(chǎn)系統(tǒng)進(jìn)行最終的實(shí)際更改,需要對(duì)理論進(jìn)行測(cè)試,以避免出現(xiàn)意外問題,這一點(diǎn)非常重要。您瞧,當(dāng)我在加密列期間,針對(duì)沙箱數(shù)據(jù)庫對(duì)應(yīng)用程序本身進(jìn)行了測(cè)試,從而發(fā)現(xiàn)了很多問題。最重要的是,我發(fā)現(xiàn)進(jìn)行中的加密延長(zhǎng)了某些查詢的響應(yīng)時(shí)間,以至于應(yīng)用程序會(huì)遇到響應(yīng)超時(shí)。這些超時(shí)又會(huì)造成連接斷開,然后導(dǎo)致后續(xù)的事務(wù)失敗,進(jìn)而會(huì)更加麻煩 — 我將為您提供詳細(xì)信息。

必須一提的是,測(cè)試之后,我了解到停止應(yīng)用程序運(yùn)行絕對(duì)不是沒有理由的。但下一個(gè)問題是,生產(chǎn)應(yīng)用程序需要脫機(jī)多久?在計(jì)劃每個(gè)周末進(jìn)行的正常兩小時(shí)的維護(hù)時(shí)間之內(nèi)能夠?qū)α羞M(jìn)行加密嗎?或者,需要更長(zhǎng)的停機(jī)時(shí)間?為了弄清這個(gè)問題,我只需測(cè)量在沙箱環(huán)境中對(duì)列進(jìn)行加密所花費(fèi)的時(shí)間,因?yàn)樯诚洵h(huán)境與生產(chǎn)環(huán)境具有相同的服務(wù)器硬件和數(shù)據(jù)集。我發(fā)現(xiàn),列加密要花費(fèi)一個(gè)小時(shí)多一點(diǎn)的時(shí)間才能完成。坦白地說,由于我使用類似數(shù)據(jù)在筆記本電腦上模擬測(cè)試加密運(yùn)行才花費(fèi)了不到 5 分鐘的時(shí)間,因此對(duì)于它花費(fèi)這么長(zhǎng)時(shí)間,我感到非常震驚。但是當(dāng)我們?cè)谏a(chǎn)數(shù)據(jù)庫系統(tǒng)中對(duì)列進(jìn)行加密時(shí),最要緊的是要使用陳舊服務(wù)器硬件所發(fā)生的情況。

了解到在正常維護(hù)時(shí)間內(nèi)執(zhí)行其他任務(wù)需要更多時(shí)間,我決定必須找到減少加密列花費(fèi)時(shí)間的方法。我的第一個(gè)直覺就是刪除包含目標(biāo)列的兩個(gè)索引。這樣,Oracle 只需加密表本身中的列數(shù)據(jù),之后我可以有效地重建索引,而沒有日志記錄開銷。經(jīng)過一些新的測(cè)試之后,我將加密列以及相關(guān)索引所需的時(shí)間從 70 分鐘(在加密期間存在索引)減少到僅 20 分鐘(加密列后重建索引)。列表 2 是我用來得出結(jié)論的測(cè)試示例(從我們?cè)诹斜?1 中停止的位置繼續(xù))。此外,請(qǐng)注意,列表中的時(shí)間來自用來編寫本文的測(cè)試系統(tǒng),而不是來自我的客戶端使用的實(shí)際系統(tǒng)。

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要快速執(zhí)行對(duì)現(xiàn)有數(shù)據(jù)進(jìn)行加密的過程,只需在對(duì)其進(jìn)行加密之前刪除列的底層索引,然后再重建索引。

注:本文的模擬環(huán)境中使用了 CREATE INDEX 語句。在實(shí)際的設(shè)置中,可考慮使用 Oracle 數(shù)據(jù)庫的 DBMS_METADATA 實(shí)用程序包來生成 CREATE INDEX 語句,您可以使用這些語句在完成數(shù)據(jù)加密之后重新創(chuàng)建索引。

總之,在列加密之后重建索引的新策略可留出更多時(shí)間來處理整個(gè)過程中最具挑戰(zhàn)性的問題,這將在下一部分中進(jìn)行說明。

刪除未加密數(shù)據(jù)的虛副本

Oracle 和底層主機(jī)操作系統(tǒng)使用優(yōu)化的算法來更新數(shù)據(jù)塊中的數(shù)據(jù),目的是最大程度地減少降低性能的磁盤 I/O。在對(duì)現(xiàn)有列數(shù)據(jù)進(jìn)行加密的特定情況下,通常發(fā)生的一件事是 Oracle 將加密的列數(shù)據(jù)寫入到新數(shù)據(jù)塊并且只是將之前未加密的值占用的空間標(biāo)記為未使用。換句話說,Oracle 不會(huì)嘗試清除較舊的未加密數(shù)據(jù)。只要所討論的系統(tǒng)持續(xù)遇到大量更新活動(dòng),您就有理由確信當(dāng)重用塊空間時(shí) Oracle 將最終覆蓋較舊的未加密數(shù)據(jù)。但是考慮到我的客戶正在準(zhǔn)備進(jìn)行合規(guī)性審計(jì),我必須確保在加密過程之后立即擦除未加密的敏感數(shù)據(jù)。

進(jìn)行了很多研究之后,我在 Oracle 技術(shù)網(wǎng)上發(fā)現(xiàn)了一個(gè) FAQ 以及一個(gè)網(wǎng)志,該網(wǎng)志確認(rèn)這一特定問題并提供了有關(guān)解決該問題的一些基本想法。一般的想法是將包含之前未加密數(shù)據(jù)的所有段移動(dòng)到新的表空間(以及數(shù)據(jù)文件),然后使用一個(gè)操作系統(tǒng)實(shí)用程序刪除舊數(shù)據(jù)文件。但該做法聽起來容易,做起來難。事實(shí)是,在安全刪除舊表空間及其數(shù)據(jù)文件之前,您很有可能需要移動(dòng)大量段以及包含敏感數(shù)據(jù)的段。

為了使這一可能費(fèi)時(shí)費(fèi)力且易于出錯(cuò)的過程自動(dòng)進(jìn)行,我將一些腳本放在一起,以幫助我構(gòu)建完成這一切所需的 DDL 語句。這里,我要向 Tom Kyte 表示謝意,因?yàn)榇颂幍囊恍┕ぷ魇切薷奈以?Asktom 站點(diǎn)找到的內(nèi)容查詢。列表 3 顯示了我使用的整個(gè)過程的一個(gè)示例。

Enter password:

Connected.

SQL> -- Create new tablespaces for data and index segments

SQL> CREATE TABLESPACE data_002 DATAFILE SIZE 1G;

Tablespace created.

SQL> CREATE TABLESPACE indx_002 DATAFILE SIZE 500M;

Tablespace created.

SQL> -- Generate a script to move existing segments to new tablespaces

SQL> COL ORDER_COL1 NOPRINT;

SQL> COL ORDER_COL2 NOPRINT;

SQL> SET HEADING OFF;

SQL> SET VERIFY OFF;

SQL> SET ECHO OFF;

SQL> SELECT DECODE( segment_type, 'TABLE' , segment_name, table_name ) order_col1,

2 DECODE( segment_type, 'TABLE', 1, 2 ) order_col2,

3 'ALTER ' || segment_type || ' ' || LOWER(owner) || '.' || LOWER(segment_name) ||

4 DECODE( segment_type, 'TABLE', ' MOVE ', ' REBUILD ' ) ||

5 'TABLESPACE ' || LOWER(DECODE( segment_type, 'TABLE' , '&&NEW_DATA_TBS' , '&&NEW_INDX_TBS' )) || ';'

6 FROM dba_segments,

7 (SELECT table_name, index_name FROM dba_indexes WHERE tablespace_name = UPPER('&&OLD_INDX_TBS'))

8 WHERE segment_type in ( 'TABLE', 'INDEX' )

9 AND segment_name = index_name (+)

10 AND tablespace_name IN (UPPER('&&OLD_DATA_TBS'), UPPER('&&OLD_INDX_TBS'))

11 AND owner = UPPER('&&OWNER')

12 ORDER BY 1, 2;

Enter value for new_data_tbs: data_002

Enter value for new_indx_tbs: indx_002

Enter value for old_indx_tbs: indx_001

Enter value for old_data_tbs: data_001

Enter value for owner: app_001

ALTER TABLE app_001.transactions MOVE TABLESPACE data_002;

ALTER INDEX app_001.transactions_pk REBUILD TABLESPACE indx_002;

ALTER INDEX app_001.transactions_ndx1 REBUILD TABLESPACE indx_002;

SQL> SET HEADING ON;

SQL> SET VERIFY ON;

SQL> SET ECHO ON;

SQL> -- execute script output

SQL> ALTER TABLE app_001.transactions MOVE TABLESPACE data_002;

Table altered.

SQL> ALTER INDEX app_001.transactions_pk REBUILD TABLESPACE indx_002;

Index altered.

SQL> ALTER INDEX app_001.transactions_ndx1 REBUILD TABLESPACE indx_002;

Index altered.

SQL> -- Check for any unusable indexes

SQL> SELECT owner, index_name, tablespace_name

2 FROM dba_indexes

3 WHERE STATUS = 'UNUSABLE';

no rows selected

SQL> -- Gather new schema stats

SQL> EXEC dbms_stats.gather_schema_stats('app_001');

PL/SQL procedure successfully completed.

SQL> -- Check for remaining segments in old tablespaces

SQL> SELECT distinct owner

2 FROM dba_segments

3 WHERE tablespace_name IN (UPPER('&&OLD_DATA_TBS'), UPPER('&&OLD_INDX_TBS'));

old 3: WHERE tablespace_name IN (UPPER('&&OLD_DATA_TBS'), UPPER('&&OLD_INDX_TBS'))

new 3: WHERE tablespace_name IN (UPPER('data_001'), UPPER('indx_001'))

no rows selected

SQL> -- Check for users assigned to old tablespaces

SQL> SELECT username, default_tablespace FROM dba_users

2 WHERE default_tablespace IN (UPPER('&&OLD_DATA_TBS'), UPPER('&&OLD_INDX_TBS'));

old 2: WHERE default_tablespace IN (UPPER('&&OLD_DATA_TBS'), UPPER('&&OLD_INDX_TBS'))

new 2: WHERE default_tablespace IN (UPPER('data_001'), UPPER('indx_001'))

USERNAME DEFAULT_TABLESPACE

------------------------------ ------------------------------

APP_001 DATA_001

SQL> -- Assign new default tablespaces for users, as necessary

SQL> ALTER USER app_001

2 DEFAULT TABLESPACE data_002;

User altered.

SQL> -- List the data file names of old tablespaces

SQL> COL tablespace_name FOR A15;

SQL> COL file_name FOR A70;

SQL> SET LINES 100;

SQL> SELECT tablespace_name, file_name

2 FROM dba_data_files

3 WHERE tablespace_name IN (UPPER('&&OLD_DATA_TBS'), UPPER('&&OLD_INDX_TBS'));

old 3: WHERE tablespace_name IN (UPPER('&&OLD_DATA_TBS'), UPPER('&&OLD_INDX_TBS'))

new 3: WHERE tablespace_name IN (UPPER('data_001'), UPPER('indx_001'))

TABLESPACE_NAME FILE_NAME

--------------- ----------------------------------------------------------------------

DATA_001 /data01/oracle/db001/datafile/o1_mf_data_001_4m081w7m_.dbf

INDX_001 /data01/oracle/db001/datafile/o1_mf_indx_001_4m082l4q_.dbf

SQL> -- Drop old tablespaces, but keep data files in place

SQL> DROP TABLESPACE data_001

2 INCLUDING CONTENTS KEEP DATAFILES;

Tablespace dropped.

SQL> DROP TABLESPACE indx_001

2 INCLUDING CONTENTS KEEP DATAFILES;

Tablespace dropped.

SQL> -- Shred/remove old data files

SQL> HOST shred -n 200 -z -u /data01/oracle/db001/datafile/o1_mf_data_001_4m081w7m_.dbf

SQL> HOST shred -n 200 -z -u /data01/oracle/db001/datafile/o1_mf_indx_001_4m082l4q_.dbf

列表 3刪除剩余敏感數(shù)據(jù)的未加密虛副本需要一系列步驟才能解決很多相關(guān)性。

列表 3 中的最后一步針對(duì)特定的操作系統(tǒng)。在本例中,我演示了 Linux/Unix shred 實(shí)用程序的用法。其他您可能想探究的實(shí)用程序是 Linux/Unix wipe、scrub 和 srm 程序。

準(zhǔn)備可能的重新生成密鑰操作

我的客戶還想做些準(zhǔn)備以應(yīng)對(duì)將來可能需要重新生成密鑰的情況。為現(xiàn)有數(shù)據(jù)重新生成密鑰意味著您要使用新密鑰對(duì)現(xiàn)有數(shù)據(jù)重新加密。當(dāng)您懷疑某人已經(jīng)獲得對(duì)現(xiàn)有表密鑰的訪問權(quán)限并且可能會(huì)在您的控制之外破解敏感數(shù)據(jù)時(shí),可能需要執(zhí)行該操作。

完成重新生成密鑰操作的步驟與最初加密現(xiàn)有數(shù)據(jù)的步驟類似:刪除目標(biāo)列上的索引,重新生成該列數(shù)據(jù)的密鑰,然后重建刪除的索引。或者,如果您擔(dān)心與使用以前的密鑰加密的數(shù)據(jù)相對(duì)應(yīng)的虛副本,可以重復(fù)將段移動(dòng)到新表空間、刪除舊表空間、然后清除舊表空間的數(shù)據(jù)文件的過程。

注:以我的經(jīng)驗(yàn),PCI 審計(jì)員會(huì)對(duì)重新生成萬能加密密鑰非常滿意,因?yàn)樵撨^程不需要訪問任何數(shù)據(jù),并且 PCI 標(biāo)準(zhǔn)不包含對(duì) 2 層密鑰體系結(jié)構(gòu)(如 Oracle 的體系結(jié)構(gòu))的建議。從符合 PCI 的角度看,重新生成萬能加密密鑰應(yīng)該足夠了,而且 PCI 審計(jì)員無法強(qiáng)制具有幾十億行的公司將其業(yè)務(wù)關(guān)閉幾天,僅僅只是為了重新生成密鑰。

確定可能的查詢計(jì)劃更改

Oracle 文檔、若干文章以及我閱讀過的一些論壇帖子幾乎都提到了有關(guān)加密列的數(shù)據(jù)后現(xiàn)有查詢執(zhí)行計(jì)劃可能發(fā)生更改的概要信息以及某些具體信息。一般來說,相對(duì)于沒有索引的列,在加密具有索引的列時(shí),您必須注意執(zhí)行 SQL 語句所發(fā)生的情況。當(dāng) Oracle 加密具有索引的列時(shí),Oracle 還將加密相應(yīng)的索引值。如果您花點(diǎn)時(shí)間考慮這個(gè)問題,就會(huì)清楚地發(fā)現(xiàn)以具有索引的數(shù)據(jù)為目標(biāo)的相等謂詞應(yīng)該繼續(xù)利用索引,但由于該索引值存儲(chǔ)在索引中的方式,加密值的隨機(jī)性質(zhì)使得加密索引的范圍掃描成本過高。列表 4 演示了這些詳細(xì)描述的基本情況。

SQL> CONNECT app_001

Enter password:

Connected.

SQL> -- Create a plan table

SQL> @?/rdbms/admin/utlxplan.sql;

Table created.

SQL> -- Disable encryption of the credit card column

SQL> ALTER TABLE app_001.transactions

2 MODIFY (credit_card DECRYPT);

Table altered.

SQL> -- Ensure schema stats are current

SQL> EXEC dbms_stats.gather_schema_stats('app_001');

PL/SQL procedure successfully completed.

SQL> -- Display some representative data

SQL> COL credit_card FOR 9999999999999999;

SQL> SELECT * FROM app_001.transactions

2 WHERE rownum <5;

TRANS_ID CREDIT_CARD

---------- -----------------

389 3469681098409570

390 3441050723354352

391 3485598407754404

392 3485458104610650

SQL> -- Enable tracing and explain plan output

SQL> SET AUTOTRACE ON EXPLAIN;

SQL> -- Demonstrate an equality predicate targeting the

SQL> -- encrypted column

SQL> SELECT * FROM app_001.transactions

2 WHERE credit_card = 3485458104610650;

TRANS_ID CREDIT_CARD

---------- -----------------

392 3485458104610650

Execution Plan

----------------------------------------------------------

Plan hash value: 32329967

-------------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 14 | 5 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| TRANSACTIONS | 1 | 14 | 5 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | TRANSACTIONS_NDX1 | 1 | | 3 (0)| 00:00:01 |

-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access('CREDIT_CARD'=3485458104610650)

SQL> -- Demonstrate a range predicate targeting the

SQL> -- encrypted column

SQL> SELECT * FROM app_001.transactions

2 WHERE credit_card BETWEEN 3499990000000000 AND 3499999999999999;

TRANS_ID CREDIT_CARD

---------- -----------------

4629 3499990987277941

18597 3499993250694089

13364 3499996558049599

79326 3499996616476145

60420 3499997873591732

24392 3499998608513414

97433 3499999831086288

72183 3499999977925392

8 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 32329967

-------------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 3 | 42 | 6 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| TRANSACTIONS | 3 | 42 | 6 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | TRANSACTIONS_NDX1 | 3 | | 3 (0)| 00:00:01 |

-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access('CREDIT_CARD'>=3499990000000000 AND 'CREDIT_CARD'<=3499999999999999)

SQL> -- Disable tracing and explain plan output

SQL> SET AUTOTRACE OFF;

SQL> -- Encrypt the column (and indexes)

SQL> ALTER TABLE app_001.transactions

2 MODIFY (credit_card ENCRYPT NO SALT);

Table altered.

SQL> -- Ensure schema stats are current

SQL> EXEC dbms_stats.gather_schema_stats('app_001');

PL/SQL procedure successfully completed.

SQL> -- Enable tracing and explain plan output

SQL> SET AUTOTRACE ON EXPLAIN;

SQL> -- Rerun previous queries, compare execution plans

SQL> SELECT * FROM app_001.transactions

2 WHERE credit_card = 3485458104610650;

TRANS_ID CREDIT_CARD

---------- -----------------

392 3485458104610650

Execution Plan

----------------------------------------------------------

Plan hash value: 32329967

-------------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 14 | 5 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| TRANSACTIONS | 1 | 14 | 5 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | TRANSACTIONS_NDX1 | 1 | | 3 (0)| 00:00:01 |

-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access('CREDIT_CARD'=3485458104610650)

SQL> SELECT * FROM app_001.transactions

2 WHERE credit_card BETWEEN 3499990000000000 AND 3499999999999999;

TRANS_ID CREDIT_CARD

---------- -----------------

60420 3499997873591732

4629 3499990987277941

18597 3499993250694089

13364 3499996558049599

24392 3499998608513414

79326 3499996616476145

72183 3499999977925392

97433 3499999831086288

8 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 1321366336

----------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1250 | 17500 | 914 (2)| 00:00:11 |

|* 1 | TABLE ACCESS FULL| TRANSACTIONS | 1250 | 17500 | 914 (2)| 00:00:11 |

----------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - filter(INTERNAL_FUNCTION('CREDIT_CARD')>=3499990000000000 AND

INTERNAL_FUNCTION('CREDIT_CARD')<=3499999999999999)

SQL> -- Disable tracing and explain plan output

SQL> SET AUTOTRACE OFF;

列表 4 仔細(xì)識(shí)別引用加密列數(shù)據(jù)的 SQL 語句,然后比較加密前后這些語句的執(zhí)行計(jì)劃,以查找是否存在任何更改。

我還想知道加密的開銷是否會(huì)改變計(jì)劃成本以及優(yōu)化程序的選擇,即使在文檔建議不要這樣做的情況下。為了確保我確切知道進(jìn)行生產(chǎn)時(shí)關(guān)鍵任務(wù)應(yīng)用程序所發(fā)生的情況,我在沙箱環(huán)境中進(jìn)行了一些額外的工作。首先,我從各種自動(dòng)負(fù)載信息庫 (AWR) 快照中收集了一個(gè)使用頻繁的 SQL 語句(CPU、Gets 和 I/O)列表。然后,我比較了加密列前后每個(gè) SQL 語句的查詢執(zhí)行計(jì)劃。我的研究轉(zhuǎn)向?qū)Χ鄠€(gè)基于相等的條件使用一個(gè)謂詞的復(fù)雜查詢,其中一個(gè)條件是以將要進(jìn)行加密的列為目標(biāo)。讓我吃驚的是,在對(duì)列進(jìn)行加密之后,該查詢的執(zhí)行計(jì)劃發(fā)生了改變。遺憾的是,我無法在我的測(cè)試實(shí)驗(yàn)室中為本文復(fù)制這些結(jié)果,我仍然無法完全確定查詢計(jì)劃發(fā)生改變的原因。但我之所以在此處提到這種情況是想指出,在對(duì)生產(chǎn)系統(tǒng)進(jìn)行更改之前,最好在測(cè)試環(huán)境中研究生產(chǎn)應(yīng)用程序密鑰查詢的執(zhí)行計(jì)劃。如果我假設(shè)沒有任何使用頻繁的查詢會(huì)發(fā)生改變,那么我們將對(duì)生產(chǎn)系統(tǒng)進(jìn)行更改并且不得不勉強(qiáng)拼湊一個(gè)解決方案。

此處的教訓(xùn)是,在進(jìn)行更改之前,您應(yīng)該始終對(duì)這些事項(xiàng)進(jìn)行測(cè)試,無論您在文檔和其他來源中閱讀了什么內(nèi)容都是如此。

結(jié)論

使用 Oracle 的 TDE 特性加密新表與沒有任何數(shù)據(jù)的表中的列或者現(xiàn)有表中的新列非常簡(jiǎn)單,原因是不存在任何需要擔(dān)心的相關(guān)性。相反,加密現(xiàn)有列數(shù)據(jù)需要仔細(xì)研究并在您的沙箱環(huán)境中進(jìn)行測(cè)試,然后才能在實(shí)際生產(chǎn)系統(tǒng)中實(shí)施您的計(jì)劃,因?yàn)榧用芸赡軙?huì)影響很多相關(guān)性。

Steve Bobrowski自 Oracle 數(shù)據(jù)庫版本 5 開始一直使用該軟件,曾就職于 Oracle;他還是 The Database Domain (dbdomain.com) 的創(chuàng)始人以及五本 Oracle 出版社出版的書籍的作者(包括《Oracle 數(shù)據(jù)庫 10g 快捷版上機(jī)操作》系列)。最近,Steve 擔(dān)任著幾個(gè)大型公司(如 Computer Sciences Corporation、BEA Systems 和 Salesforce.com)的 SaaS 顧問和 SaaS 首席技術(shù)官。

標(biāo)簽: Oracle 數(shù)據(jù)庫
相關(guān)文章:
主站蜘蛛池模板: 国产精品免费视频网站 | 欧美成人免费网在线观看 | 久久精品视频国产 | 一级毛片在线看在线播放 | 国产老肥熟xxxx | 婷婷色九月 | 国产精品一区高清在线观看 | 人与鲁牲交持级毛片 | 亚洲性一级理论片在线观看 | 国产精品嫩草视频永久网址 | 日韩在线不卡 | 亚洲性一级理论片在线观看 | 免费毛片无需任何播放器 | 国产hs免费高清在线观看 | 国产精品爽爽影院在线 | a毛片免费全部在线播放毛 a毛片免费全部播放毛 | 色综合久久中文 | 99久久综合狠狠综合久久一区 | 四虎现在的网址入口2022 | 国产精品久久久久久久久免费hd | 欧美一级毛片高清毛片 | 欧美成人免费毛片 | 成人福利在线视频 | 林美仑在线三级播放 | 欧美专区在线 | 中国成熟xxx视频 | 爱爱激情网 | igao视频天堂 | 亚洲欧美日韩视频一区 | 黄色一级免费观看 | 日本视频二区 | 中文字幕亚洲欧美日韩不卡 | 看全色黄大色黄大片色责看的 | 天天欲色成人综合网站 | 日韩特级片 | 国产亚洲精品久久 | 91专区在线观看 | 大美香蕉伊在看欧美 | 成人无高清96免费 | 国产精品亚洲高清一区二区 | 日韩一级片在线 |