Oracle 資料庫加密
資料加密
動態資料(data in motion)和靜態資料(data at rest),除了手動加密,其他的加密都需要oracle企業版的高階加密(額外收費——)
1 靜態資料加密
Example:
1 建立一個新的表空間
create tablespace in_the_clear
datafile 'f:\mydb\in_the_clear.dbf' size 1m
建立一個表
create table t_clear ( id varchar2(30) primary key, ssn varchar2(11), address varchar2(80), credit_card varchar2(30) ) tablespace in_the_clear; insert into t_clear (id, ssn, address, credit_card ) values ( 'Look for me', '123-45-6789', '123 Main Street', '1234-5678-9876-5432' );
然後commit;
Alter system checkpoint;--觸發檢查點事件。
- !strings -a /tmp/in_the_clear.dbf | egrep '(Look for me|123)'
- Linux下檢視該資料檔案的內容
Oracle把資料型別為number和date的值按原樣儲存,
如果delete刪除了資料,資料仍留在原處,它會保留在資料檔案中,除非被其他資料覆蓋或者直到有其他資料覆蓋,
還可以根據redo檔案跟一些歸檔檔案來查出大量資訊,還可以根據undo表空間找出一些資料,對於redo檔案,oracle提供了log miner工具,可以來檢查資料檔案的內容
select a.member from v$logfile a, v$log b where a.group# = b.group# and b.status = 'CURRENT' and rownum = 1;
F:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04.LOG
獲取當前的線上重做日誌檔案。
!strings -a &REDO | egrep '(Look for me|123)'
2 oracle錢夾
Oracle建議使用多個錢夾,錢夾儲存在資料庫之外,
2.1 建立錢夾
在資料庫伺服器的sqlnet.ora配置檔案中作一個修改,
F:\oracle\product\10.2.0\db_1\NETWORK\ADMIN
SQLNET.AUTHENTICATION_SERVICES= (NTS)
# NAMES.DIRECTORY_PATH= (TNSNAMES)
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
ENCRYPTION_WALLET_LOCATION=
(SOURCE=(METHOD=FILE)
(METHOD_DATA=
(DIRECTORY=f:\mydb\) ---指定存放錢夾的目錄
)
)
然後
shutdown immediate
startup
ALTER SYSTEM SET ENCRYPTION KEY identified by yhq1314;
ALTER SYSTEM SET ENCRYPTION KEY identified by foobar;
需要開啟或者關閉,在資料開啟的時候
idle> ALTER SYSTEM SET ENCRYPTION WALLET OPEN IDENTIFIED BY foobar;
idle> ALTER SYSTEM SET ENCRYPTION WALLET close IDENTIFIED BY foobar;
在以後重啟例項後或者關閉了錢夾後,想要查詢經過加密的資料,必須開啟錢夾
2.2 透明列級加密(10g)
create table t_clear ( id varchar2(30) primary key, ssn varchar2(11), address varchar2(80), credit_card varchar2(30) encrypt ) tablespace in_the_clear; credit_card varchar2(30) encrypt ----預設情況下采用192位金鑰長度的AES演算法。
Encrypt後面 可以加
Using ‘xx’選擇對這列使用什麼演算法aes還是des等
Identified by 密碼,指定加密資料使用特定的密碼
Salt或no salt
可以手動取消該列的加密
alter table t_clear modify(credit_card decrypt)
同樣可以在加密
alter table t_clear modify(credit_card encrypt )
create index idx_credit_card on t_clear(credit_card)—無法對該列建立索引
這樣必須在開啟錢夾後才能對t_clear表的credit_card列進行操作(dml,select等)
1 加密列的統計資訊
對列加密會帶來副作用,改變查詢計劃,
2 列加密的限制
使用索引的能力降低
使用索引時的保護減弱,
無法使用基於函式的索引
無法使用外接約束
2.3 透明表空間加密(11g)
create tablespace encrypted
datafile '/tmp/encrypted.dbf' size 1m
ENCRYPTION default storage ( ENCRYPT );
表空間的加密的儲存沒有開銷,
3 手動加密實現
手動加密需要使用oracle的2個內建包來實現
Dbms_crypto:更容易鍵入和讀出,支援DES,3DES,RC4,AES還能生成多種雜湊和訊息驗證碼,如MD5,MD4,SHA-1,能處理RAW,CLOB,BLOB資料型別
手動加密的列必須是raw列型別,必須是16的整數倍,
CREATE OR REPLACE FUNCTION md5_digest(input_string IN VARCHAR2) RETURN VARCHAR2
IS
hex_digest varchar2(32);
digest varchar2(32);
BEGIN
digest := DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => input_string);
SELECT Lower(RAWTOHEX(digest)) INTO hex_digest FROM dual;
RETURN hex_digest;
END;
利用 Dbms_crypto
Desc Dbms_crypto
Grant execute on Dbms_crypto to scott
Grant execute on dbms_lock to scott
Md5
CREATE OR REPLACE FUNCTION md5_digest1(input_string IN VARCHAR2) RETURN VARCHAR2 IS l_hash raw(32); BEGIN l_hash := dbms_crypto.hash( src=>input_string, typ=>dbms_crypto.hash_md5); dbms_output.put_line('digest2=='||l_hash); RETURN l_hash; END; /
select md5_digest1('123456') from dual
declare l_src_date clob := '123456'; l_hash raw(200); begin l_hash := dbms_crypto.hash( src=>l_src_date, typ=>dbms_crypto.hash_md5); dbms_output.put_line(l_hash); end;
des
DECLARE l_credit_card_no VARCHAR2(19) := '1234-5678-9012-3456'; l_ccn_raw RAW(128) := utl_raw.cast_to_raw(l_credit_card_no); l_key RAW(128) := utl_raw.cast_to_raw('abcdefgh'); l_encrypted_raw RAW(2048); l_decrypted_raw RAW(2048); BEGIN dbms_output.put_line('Original : ' || l_credit_card_no); l_encrypted_raw := dbms_crypto.encrypt(l_ccn_raw, dbms_crypto.des_cbc_pkcs5, l_key);
dbms_output.put_line('Encrypted : ' || RAWTOHEX(utl_raw.cast_to_raw(l_encrypted_raw)));
l_decrypted_raw := dbms_crypto.decrypt(src => l_encrypted_raw, typ => dbms_crypto.des_cbc_pkcs5, key => l_key);
dbms_output.put_line('Decrypted : ' || utl_raw.cast_to_varchar2(l_decrypted_raw));
END;