oracle透明數據加密TDE

 

 本文轉自:http://blog.csdn.net/yah99_wolf/article/details/4586209

感謝博主:yah99_wolf

1 TDE如何工作?
 
現在我們概述一下關鍵點:加密時你需要應用一個加密算法和一個加密密鑰對明文輸入的數據進行加解密操作;爲了能夠成功的解密,你必須知道加密採用的算法和密鑰。
 
你所要做的只是定義需要加密的列,Oracle 10g數據庫將爲包含加密列的表創建一個私密(譯者注:用戶不需要知道)的安全加密密鑰,然後採用你指定的加密算法加密指定列的明文數據。
 
這種機制下,保護表的加密密鑰(以下簡稱“表密鑰”)就顯得非常重要了。Oracle 10g通過一個master密鑰來對錶密鑰進行加密。master密鑰保存在一個叫做“錢夾(wallet)”的安全的地方,錢夾可以是數據庫服務器上的一個文件,加密的表密鑰保存在數據字典中。
 
當用戶插入數據到需要加密的列中的時候,Oracle 10g從錢夾中獲取master密鑰,用master密鑰解密數據字典中的表密鑰,然後用解密後的表密鑰加密輸入數據,再將加密後的數據保存在數據庫中。如下圖1所示:
1:TDE工作原理
你可以加密表的部分或者所有列,例如一個表有4列,如上圖1所示,第2列和第3列被加密,但Oracle只會生成一個表級的加密密鑰,然後用這個密鑰加密所有的加密列。在磁盤上,第1列和第4列是明文存儲的,第2列和第3列是加密存儲的。由於數據是加密存儲的,所有後續的組建例如備份和歸檔日誌,都是加密的格式。
 
當用戶查詢一個加密列的時候,Oracle 10g透明的(譯者注:用戶不可感知)將加密的表密鑰從數據字典中取出,再取出master密鑰,然後解密表密鑰,再用解密後的表密鑰來解密磁盤上加密的數據,最後返回明文給用戶。
 
通過這種加密數據的方式,即使保存在磁盤上的數據被盜,由於master密鑰並沒有被盜,沒有master密鑰的情況下,數據無法被獲取。即使“錢夾(wallet)”被盜,如果沒有錢夾密碼(譯者注:TDE涉及3個密碼,一個是錢夾密碼,用來啓動錢夾;一個是master密鑰,用來加解密表密鑰;一個是表密鑰,用來加解密數據,錢夾密碼是用戶手工輸入的,master密鑰和表密鑰是系統管理的),master密鑰還是無法獲取。因此,即使竊賊盜取了磁盤或者數據文件的拷貝,也無法解密數據。這樣做滿足了很多規則和指南的要求,而所有的這些並不需要修改應用程序或者編寫複雜的加密和密鑰管理系統。
 
接下來我將向你展示如何開啓和使用TDE。
 
1.1 一次安裝
 
你第一次使用TDE時,必須1)指定“錢夾”的位置,2)設置錢夾密碼,3)打開錢夾
 
指定錢夾位置
 
當你第一啓用TDE,必須創建錢夾。缺省情況下,錢夾創建於$ORACLE_BASE/admin/$ORACLE_SID/wallet目錄下。
你也可以通在位於$ORACLE_HOME/network/admin目錄下的sqlnet.ora文件中指定的方式選擇一個不同的目錄。例如:如果你想講錢夾放在/orawall目錄下,在sqlnet.ora文件中寫入如下內容:
 
ENCRYPTION_WALLET_LOCATION =
(SOURCE=
(METHOD=file)
(METHOD_DATA=
(DIRECTORY=/orawall)))
 
在如下的樣例中,我們將假設錢夾位於缺省的位置下。你也應該在常規的備份中包含錢夾。
注意:我在測試時候監聽起不來,報錯ora-28353。
 
創建錢夾
 
現在,你必須創建錢夾,而且必須設定訪問密碼。爲了能夠完成此操作,通過如下的操作給一個用戶賦予特權(privilege):
  • 進入到步驟1中指定的目錄下,創建了一個錢夾, 如mkdir wallet
  • 設定了錢夾的密碼爲“XXXXXX”: alter system set encryption key identified by XXXXXX;
  • 打開了用於TDE存儲和獲取master密鑰的錢夾
錢夾密碼是大小寫敏感的且必須用雙引號括起來。密碼“XXXXXX”在任何動態性能視圖或者日誌中都不會顯示爲明文。
 
(alter system set encryption key authenticated by "remnant";此命令自動創建錢夾及密碼)
 
打開錢夾
 
由於錢夾只需要創建一次,因此上面的兩個步驟只需要執行一次。錢夾必須顯式的在數據庫啓動後打開。當你創建錢夾的同時錢夾也被打開了。當創建錢夾且設定密碼後,每次打開數據庫的時候,你都必須使用密碼按照如下方式打開錢夾:
 
alter system set encryption wallet open authenticated by "XXXXXX";
 
你可以通過如下方式關閉錢夾:
 
alter system set encryption wallet close;
 
爲了TDE能夠正常工作,錢夾必須被打開。如果錢夾被關閉,你還是可以訪問沒有加密的列,但不能夠訪問加密的列。
 
1.2 加密列
 
在一個常規的schema中,假設你有一個如下定義的名稱爲“account”表:
 
ACC_NO NUMBER
ACC_NAME VARCHAR2(30)
SSN VARCHAR2(9)
 
目前表的所有數據是明文的,你想轉換SSN列爲加密的:
 
alter table accounts modify (ssn encrypt);
 
這條語句完成了如下兩件事:
  • 爲表創建了一個表密鑰,如果你修改同一個表中的另外的列爲加密的,將會使用同一個表密鑰
  • 將所有列的值轉換爲加密的形式
這條語句並不修改數據類型或者列的長度,也不創建觸發器或者視圖。
 
缺省情況下采用192位密鑰長度的AES算法。你也可以選擇不同的算法,只需要在SQL命令中指定即可。例如,如果要使用128位的AES算法,你可以採用如下語句:
 
alter table accounts modify (ssn encrypt using 'AES128');
 
你可以使用AES128、AES192、AES256、或者3DES168。這些值是自解釋的,例如:AES256指採用AES算法、256位長度的密鑰。
 
加密列之後,當查看錶的時候你可以看到如下信息:
 
SQL> desc accounts
 
Name Null? Type
------------ ------------ --------------------------------------------------
ACC_NO NUMBER
ACC_NAME VARCHAR2(30)
SSN VARCHAR2(9) ENCRYPT
 
需要注意的是ENCRYPT關鍵字在數據類型之後。如果需要查找數據庫中加密的列,你可以在數據字典視圖中搜索DBA_ENCRYPTED_COLUMNS(TDE不能在SYS所有的表中啓用).
 
2 性能考慮
 
由於加解密消耗CPU,因此你必須考慮性能的影響。當你訪問表中不加密的列時,性能和不使用TDE的表沒有任何差別。只有在訪問加密列的時候,會有小的性能負擔,包括查詢加密列和插入加密列,因此你也許想有選擇的加密列。
 
如果你不再需要對一個列加密,你可以通過如下方式關閉加密功能:
 
alter table account modify (ssn decrypt);
 
索引的使用也必須考慮。在上面的樣例中,讓我們假設在SSN列上有一個叫做in_accounts_ssn的索引。如果針對ACCOUNT表的查詢有一個相等的謂詞,如下所示:
 
select * from accounts where ssn = '123456789';
 
這樣in_accounts_ssn就會用到。如果用LIKE謂詞來代替,如下所示:
 
select * from accounts where ssn like '123%';
 
則索引不會被用到,而會採用整表掃描的方式。原因很簡單,索引的B-樹結構保證了具有相同前綴的值—例如"fraternal", "fraternity"等等在物理上是相鄰的。當處理LIKE謂詞時,Oracle 10g通過模式匹配來搜索索引入口(entry),物理上相鄰有助於加快索引搜索速度,這樣也比整表掃描要好一些。
然而,如果列被加密了,索引上實際的值就完全不一樣了(因爲它們被加密了),因此原來相鄰的數據被分散在整個索引上了。這樣導致索引掃描筆整表掃描更加消耗性能。因此對於LIKE謂詞,Oracle 10g將忽略索引,而直接採用整表掃描。
 
在相等匹配的謂詞情況下,搜索指定索引取代了按值進行模式匹配,所以使用索引執行比整表掃描要更快,數據庫優化器會選擇使用索引。
 
當你決定加密某列,考慮加密如何影響索引,而且要特別小心你可能想重寫涉及加密列的特定查詢。
 
3密鑰和密碼管理
 
萬一有人得到了表密鑰,或者你懷疑某人可能已經破解了加密的表密鑰,你該如何操作?
你可以簡單的爲表創建一個新的密鑰,換句話說就是重新生成密鑰,然後通過如下語句將所有加密列用新密碼重新進行加密。你也許會想選擇另外一個算法進行加密,例如AES256,你可以通過如下方式同時完成兩件事:
 
alter table accounts rekey using 'aes256';
 
萬一有人得到了錢夾的密碼怎麼辦呢?
 
你可以通過Oracle Wallet Manager修改錢夾密碼,在命令行中輸入OWM即可調用如下GUI工具。從頂上的菜單選擇Wallet -> Open並且選擇你指定的錢夾的位置,然後給出錢夾密碼,選擇Wallet -> Change Password修改錢夾密碼。需要說明的是修改錢夾的密碼不會修改master密鑰。
2:Oracle Wallet Manager
 
4 如何處理“Salt”
加密是關於如何隱藏數據的,但是如果原始的明文數據有很多重複的數據時,有時很容易能夠猜出加密數據的原始值。例如,一個關於薪水信息的表將包含很多重複的值,這種情況下,加密後的值也是一樣的。一個***者能夠確定同一薪水的所有索引入口。爲了防護這種情況,將“salt”加入到數據中使得即使原始值相同的數據加密後具有不同的加密值。TDE缺省情況下應用了“salt”技術。
 
如果你準備在一個加密的列上創建索引,因此你不能包含“salt”。通過以下方式可以將“salt”從SSN列上移除:
 
alter table accounts modify
(ssn encrypt no salt);
 
如果你準備在一個包含“salt”的加密列上創建索引,你將得到一個錯誤提示,就像下面的樣例所示:
 
SQL> create index in_acc_01
on accounts (ssn);
 
ORA-28338: cannot encrypt indexed column(s) with salt
 
當你準備加密一個包含“salt”的列時,你將會得到同樣的錯誤。同樣的,如果列上有一個隱含的索引,例如列是主鍵的一部分,或者列被定義爲unique,你將也不能使用加密。以此推斷,當一個列是外鍵的一部分時,你也不能使用salt。
 
5 導出TDE加密數據
 
缺省情況下,如果你使用EXPDP工具導出一個擁有加密列的表,在導出文件(dump file)中列是明文的,即使列定義爲加密也是如此。如下命令導出ACCOUNTS表(包括加密的列),將會返回一個警告:
 
$ expdp arup/arup tables=accounts
 
ORA-39173: Encrypted data has been stored unencrypted in dump file set.
 
當然,這只是一個警告,不是錯誤,數據還是會被導出。
 
爲了在數據導出文件中保護你的加密的列數據,你可以在導出表的時候通過密碼保護機制來保護導出文件。這個密碼通過在EXPDP命令中的ENCRYPTION_PASSWORD參數指定,且只會應用到本次導出,這個不是“錢夾”的密碼(譯者注:和TDE沒有關係)。如下清單演示了在EXPDP命令中加上“pooh”密碼。需要注意的是清單1中的密碼並不會顯示爲“pooh”,而是通過*號來隱藏。最終導出來的dump文件中將不會看到通過TDE加密的列的明文數據了。
 
代碼清單1:導出密碼保護的dump文件
 
$ expdp arup/arup ENCRYPTION_PASSWORD=pooh tables=accounts
  
當你導入加密的dump文件時,你也必須提供同樣的密碼,代碼清單2顯示瞭如何操作:
 
代碼清單2:導入密碼保護的dump文件
$ impdp arup/arup ENCRYPTION_PASSWORD=pooh tables=accounts table_exists_action=replace
 
 
如下樣例展示了在導入的時候不輸入ENCRYPTION_PASSWORD參數時的結果:
 
$ impdp arup/arup tables=accounts
 
ORA-39174: Encryption password must
be supplied.
The following shows the result if you provide the wrong password:
$ impdp arup/arup ENCRYPTION_PASSWORD
=piglet tables=accounts
 
ORA-39176: Encryption password is
incorrect.
 
注意:原有的導出工具EXP無法導出有加密列的表。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章