Oracle Transparent Data Encryption 透明加密(二)

realkid4發表於2010-12-16

這個系列主要介紹了Oracle10gR2開始推出的透明加密(Transparent Data Encryption,簡稱TDE)。在上面一篇中,我們簡單介紹了TDE的基本原理,以及如何配置使用TDE技術加密資料庫中的資料。

 

TDE是在資料庫層次進行資料保護加密的方法。存放在資料庫中的資料都是經過加密處理,而加密金鑰Key是分別存放在資料庫內和獨立資料庫儲存的。這樣帶來的好處是,一旦資料檔案、硬碟丟失,非法獲取到的資料內容是不可讀的,實現了敏感資料加密。另一方面,資料在存入資料庫、從資料庫中讀取的過程中,由資料庫自動進行加解密處理,不需要開發人員額外的工作。實現了一定意義上的透明。

 

在本篇中,我們繼續討論TDE的加密處理機制在儲存方面的效率,以及加入TDE後,對DML等操作帶來的影響。最後,想從管理和開發的角度談TDE帶給應用的機遇與挑戰。

 

TDE儲存結構

 

在使用TDE的時候,透過指定資料列是否加密,來對資料進行透明的加解密處理。插入、修改和查詢資料的時候,使用的都是明文資訊。但是,儲存在資料庫檔案中的內容,的確是加密過的內容。那麼,在儲存空間的使用上,加密處理過的資料是不是佔據更少的空間呢。我們繼續實驗。

 

首先,我們建立兩個相同條件的資料表。欄位名稱、型別全部一致,區別在於一個進行加密設定,而另一個不進行設定。

 

//建立資料表t

SQL> create table t

  2  (id number encrypt no salt primary key); //t的資料列id是加密列

 

Table created

 

//資料表t_no

SQL> create table t_no

  2  (id number primary key); //一般資料列id

 

Table created

 

建立兩個資料表的作用在於對比,之後插入相同的資料資訊。

 

//插入資料

SQL> insert into t values (10);

 

1 row inserted

 

SQL> insert into t_no values (10);

 

1 row inserted

 

SQL> commit;

Commit complete

 

資料已經插入,按照Oracle資料段分配原則:一個物件建立之後,預設分配一個區extents,包括八個資料塊block。我們選擇的資料比較簡單,所以必然在一個資料塊中。下面對資料塊進行定位。

 

SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,

  2  dbms_rowid.rowid_block_number(rowid) block#

  3  from t;

 

       FNO     BLOCK#

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

4                         5120

 

使用dbms_rowid包,可以根據rowid的資訊定位到該行所在資料塊的資訊。rowid包括物件號+資料檔案號+資料塊號+行號(slot編號)。上面說明加密表t的一條記錄在第四號檔案中的5120塊中。

 

接下來嘗試將資料塊匯出dump處理。

 

//在有alter system許可權的情況下,dump出指定的資料塊資訊;

SQL> alter system dump datafile 4 block 5120;

 

System altered

 

//獲取跟蹤檔案位置,f_get_trace_name是自定義函式,用於獲取trace檔案位置;

SQL> select f_get_trace_name from dual;

 

F_GET_TRACE_NAME

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

C:\TOOL\ORACLE\ORACLE\PRODUCT\10.2.0\ADMIN\OTS\UDUMP\ots_ora_7512.trc

 

獲取到的trace檔案,包括一個資料塊的資訊內容。其中,我們關注片段如下:

 

data_block_dump,data header at 0x8b08464

===============

tsiz: 0x1f98

hsiz: 0x14

pbl: 0x08b08464

bdba: 0x01001400

     76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f70

avsp=0x1f5c

tosp=0x1f5c

0xe:pti[0]   nrow=1      offs=0

0x12:pri[0] offs=0x1f70

block_row_dump:

tab 0, row 0, @0x1f70

tl: 40 fb: --H-FL-- lb: 0x1  cc: 1

col  0: [36]

 ee 20 fa 3c ed 79 0a 91 d6 6f 68 90 43 1d 69 36 13 d9 cf c8 e3 3e 3a 56 66

 01 de 9b 21 69 5e 8a 66 99 bf 52

end_of_block_dump

End dump data blocks tsn: 4 file#: 4 minblk 5120 maxblk 5120

 

資料行row 0,第一個col 0的取值,是一個較長的欄位,不能區分出取值10(插入資料值10)。

 

為了對比,我們再看一下資料表t_no的情況。

 

SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,

  2  dbms_rowid.rowid_block_number(rowid) block#

  3  from scott.t_no;

 

       FNO     BLOCK#

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

         4       5392

 

說明:資料表t_no的行,在檔案4號的資料塊5392上。

 

SQL> alter system dump datafile 4 block 5392;

 

System altered

 

SQL> select f_get_trace_name from dual;

 

F_GET_TRACE_NAME

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

C:\TOOL\ORACLE\ORACLE\PRODUCT\10.2.0\ADMIN\OTS\UDUMP\ots_ora_4372.trc

 

dump出的資料內容為:

 

data_block_dump,data header at 0x86e8464

===============

tsiz: 0x1f98

hsiz: 0x14

pbl: 0x086e8464

bdba: 0x01001510

     76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f92

avsp=0x1f7b

tosp=0x1f7b

0xe:pti[0]   nrow=1      offs=0

0x12:pri[0] offs=0x1f92

block_row_dump:

tab 0, row 0, @0x1f92

tl: 6 fb: --H-FL-- lb: 0x1  cc: 1

col  0: [ 2]  c1 0b

end_of_block_dump

End dump data blocks tsn: 4 file#: 4 minblk 5392 maxblk 5392

 

同樣一行資料,在相同內容下,沒有加過密的資料相對比較小。只有一個行開始標記,和直接的資料值。

 

結論:使用TDE的情況下,資料庫檔案中儲存的資料值是進行過加密的。加密過的列值一般要長於原始資料值,所以使用TDE之後資料表要比不使用大。

 

 

操作的效能損耗

 

TDE的加解密操作完全是建立在自動加解密基礎上。插入資料、修改資料的時候會自動將資料加密後存放在資料表中;選擇資料時會自動的將加密過的列值進行解密。

 

這種操作無形中是增加了資料操作的成本,那麼增加比例如何?

 

首先我們看插入操作實驗。

 

//插入

SQL> create table t

  2  (id number encrypt);

 

Table created

 

Executed in 0.062 seconds

 

SQL> select * from scott.t;

        ID

----------

 

Executed in 0.016 seconds

 

//插入操作指令碼

declare

  i number;

begin 

  for i in 1..10 loop

     insert into scott.t

     select object_id from dba_objects;

    

     if (mod(i,2)=0) then

       commit;

     end if;    

  end loop;   

  commit;

end;

/

SQL>

 

PL/SQL procedure successfully completed

 

Executed in 14.914 seconds

 

SQL> select count(*) from scott.t;

 

  COUNT(*)

----------

    527990

 

Executed in 0.109 seconds

 

對只有一個加密欄位的資料表t,插入超過52萬條資料,使用了近15s的時間。

如果不使用加密功能,效能如下:

 

SQL> create table t_no

  2  (id number);

Table created

Executed in 0.031 seconds

 

//插入指令碼結構與上述相同,此處略

 

SQL>

PL/SQL procedure successfully completed

 

Executed in 5.741 seconds

SQL> select count(*) from scott.t_no;

 

  COUNT(*)

----------

    527995

 

Executed in 0.062 seconds

 

對比之後,很容易發現兩者的差異,同樣的資料表結構(加密列除外),同樣的指令碼,同樣的資料量。不使用TDE的時間只有不到6s,相當於使用TDE的三分之一。

 

使用篩選時的情況如下:

 

//搜尋使用了加密列的資料表

SQL> select * from scott.t where id=1000;

 

        ID

----------

      1000

 

10 rows selected

 

Executed in 3.51 seconds

 

//未使用加密列的資料表搜尋

SQL> select * from scott.t_no where id=1000;

 

        ID

----------

      1000

 

10 rows selected

 

Executed in 0.14 seconds

 

差異更加明顯,在使用id作為條件的搜尋方法中。使用TDE的搜尋執行時間約4%,這也說明了使用ID進行查詢條件的時候,解析條件還需要額外的成本。

 

Oracle的官方文件中,對於使用TDE的效能問題有所涉及,認為帶來的損耗是可以接受的。一些文獻中給出的經驗值也認為損耗在20%-30%之間。但綜合上面兩個實驗:使用TDE,起碼在目前的版本中,還是會有比較大的效能問題。這是進行技術方案選型的一個重要方面考量。

 

 

TDE管理和開發

 

從目前的情況看,TDE的主要應用是在特定的資料列和特定的表空間(對錶空間TDE的使用請參考官方文件教程)。在系列的兩篇中,我們一直在強調TDE的兩個大優勢:其一是資料層面加密,加密金鑰與資料檔案分開,增加了保險係數。另一方面,是透明加密,無需直接的管理。

 

這也就是說,使用TDE只是保證了資料在資料庫中安全的,而且在wallet開啟的情況下,使用sql語句查詢實際上是沒有限制的。所以,筆者認為TDE的這種優勢在運維層面上的意義是大於開發上面的意義,起碼可以很快讓應用中的資料庫層面實現加密,無需應用層面的支援。

 

此外,TDE是不負責資料傳輸階段加密的。資料從DBMS傳出後,還是以明文方式傳輸到應用。實際上,還是需要使用安全傳輸的解決方案。

 

運維方面,要注意資料庫外層主金鑰key的保護,如果損壞或者丟失,造成損失的機率還是很高的。

 

綜上所述:TDE是一個資料庫層級的加解密解決方案。在無法修改應用、又需要對資料庫明文儲存的敏感資訊變成加密過資訊的需要下是很有效的、快速的方案。但是,考慮到TDE自身的侷限,以及帶來的效能瓶頸損耗,在系統架構方案設計和解決方案選擇的階段還是儘量避免使用。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-681943/,如需轉載,請註明出處,否則將追究法律責任。

相關文章