Upload
wasecurity
View
1.754
Download
8
Embed Size (px)
DESCRIPTION
Citation preview
Oracle 9i/10g/11g
透明数据加密 (Transparent Data Encryption)
赵元杰 整理
北京群环域科技有限公司
2012.2
2/91
内容提要
♠ Oracle 9i 数据加密技术
♠ Oracle10g TDE 技术
♠ 使用Oracle10g TDE 加密表
♠ 使用Oracle10g TDE 内置包
♠ Oracle11g TDE 技术
♠ 附录:样例
♠ 参考资源
3/91
RDBMS 数据加密
♠ 数据加密 : ♠ 加密是一种编码数据的方法,使入侵者难以理解数据内容,在授权
用户使用时,解码数据,使其返回原始格式。一些商业DBMS包含加密模块,还有一些能提供程序,使用户编写自己的加密例程
♠ 数据加密过程 : ♠ 编码数据(称为明文)的加密密钥
♠ 将明文更改为编码文本(称为密文)的加密算法
♠ 解码密文的解码密钥
♠ 将密文转换回原始明文的解密算法
4/91
数据加密技术
♠ 数据加密过程 :
♠ 一般的数据加密过程如下:
明 文
明 文
发送者
接收者
加密密钥
加密算法
解密算法解密密钥
密文
密文
5/91
数据加密技术
♠ 对称加密技术: ♠ 该技术为加密和解密使用相同加密密钥。密钥必须保密,以防范潜
在入侵者。
♠ 该技术依赖于安全通信,以便在数据提供者和授权用户之间交换密钥。若密钥确实安全,则要将密钥作为消息本身的一部分。这么做效率不高,大多数密钥较短。数据加密标准(Data Encryption
standard, 简写DES)是该技术的一个例子
♠ 非对称加密 技术: ♠ 该技术为加密和解密使用不同密钥。一种是公开的公钥,另一种是
只有授权用户知道的私钥。
♠ 加密算法也可以公开。公钥加密(RSA)是一种非对称加密方法。
6/91
数据加密技术-DES
♠ DES数据加密过程 :
♠ DES数据加密过程如下:
明 文
明 文
发送者
接收者
DES
DES
密文
密文
密钥:54269471832
密钥:54269471832
7/91
数据加密技术-DES
♠ DES数据加密原理 : ♠ DES将明文划分为块,每个块64位。用64位密钥来加密各个块。密
钥虽64位长,但有效位仅56位,其余8位用作奇偶校验位。即使56
位密钥,也可能有256种可能的不同密钥
♠ DES数据加密过程 : ♠ 使用密钥为各个块应用初始置换。
♠ 按16个连续复杂替代步骤操作转换或置换块。
♠ 最后应用另一种置换算法,与初始置换相反。
♠ DES数据解密过程 : ♠ 解密算法与加密算法相同,但步骤执行顺序正好相反。
8/91
数据加密技术-RSA
♠ RSA 的由来 :
♠ RSA 是信息安全中一个非常著名的公钥加密算法
♠ 1977 年被发明, 以该算法的三位发明人Ron Rivest、Adi Shamir、LenAdleman 的名字命名
♠ RSA 与产品 :
♠ 该算法是目前IT 系统中应用最为广泛的非对称算法。
♠ 而RSA 亦是美国一家著名的信息安全公司的名字,目前是EMC 旗下的一个分支
9/91
Oracle 9i 数据加密技术
♠ Oracle 9i 支持数据加密 :
♠ 使用DBMS_OBFUSCATION_TOOLKIT内置包
♠ DBMS_OBFUSCATION_TOOLKIT包主要包括: ♠ DESGETKEY -- 产生密钥,用于DES算法
♠ DES3GETKEY -- 产生密钥,用于Triple DES算法
♠ DESENCRYPT -- 用DES算法加密数据
♠ DESDECRYPT -- 用DES算法解密数据
♠ DES3ENCRYPT -- 用Triple DES算法加密数据
♠ DES3DECRYPT -- 用DES算法解密数据
♠ MD5 -- 用MD5算法加密数据
10/91
Oracle 9i 数据加密技术
♠ DBMS_OBFUSCATION_TOOLKIT.MD5加密: ♠ DBMS_OBFUSCATION_TOOLKIT.MD5是MD5编码的数据包函
数
♠ DBMS_OBFUSCATION_TOOLKIT.MD5返回的字串,是RAW类型,要正确显示,需要经过Utl_Raw.Cast_To_Raw转换
♠ 1、直接调用
declare
v2 varchar2(32);
begin
v2 := Utl_Raw.Cast_To_Raw(sys.dbms_obfuscation_toolkit.md5(input_string =>
'111'));
dbms_output.put_line(v2);
end;
declare
v2 varchar2(32);
begin
v2 := Utl_Raw.Cast_To_Raw(sys.dbms_obfuscation_toolkit.md5(input_string =>
'111'));
dbms_output.put_line(v2);
end;
11/91
Oracle 9i 数据加密技术
♠ DBMS_OBFUSCATION_TOOLKIT.MD5加密: ♠ 注意:可以在存储过程中直接调用,如果要嵌套调用md5时,记
得每次调用后都用Utl_Raw.Cast_To_Raw进行转换,否则最后出来的结果是错误的。
♠ 2、构造函数后,再调用
♠ 调用md5函数示例:select md5(1) from dual
CREATE OR REPLACE FUNCTION MD5(
passwd IN VARCHAR2)
RETURN VARCHAR2
IS
retval varchar2(32);
BEGIN
retval := utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING =>
passwd)) ;
RETURN retval;
END;
CREATE OR REPLACE FUNCTION MD5(
passwd IN VARCHAR2)
RETURN VARCHAR2
IS
retval varchar2(32);
BEGIN
retval := utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING =>
passwd)) ;
RETURN retval;
END;
12/91
内容提要
♠ Oracle 9i 数据加密技术
♠ Oracle10g 加密包
♠ Oracle10g TDE 加密技术
♠ Oracle10g TDE 内置包
♠ Oracle11g TDE 技术
♠ 附录:样例
♠ 参考资源
13/91
10g 加密工具包
♠ Oracle10g 具有一个简单的加密/解密接口
♠ DBMS_CRYPTO 程序包
♠ DES、3DES、AES 加密
♠ MD5 校验 和 编程密钥管理
♠ 10g 的增强用户接口
♠ 加密 blob 数据类型
♠ 应用程序必须提供密钥生成、管理和恢复功能
♠ 加密密钥必须存储在某处
♠ 可以存储在数据库文件中、操作系统中、磁盘上等等
14/91
Oracle 10g数据加密技术
♠ Oracle 10g支持数据加密 :
♠ 加密存储过程
raw_input RAW(128);
raw_key RAW(128);
encrypted_raw RAW(2048);
-- convert input to raw
encrypted_raw := dbms_crypto.Encrypt(
src => raw_input,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
raw_input RAW(128);
raw_key RAW(128);
encrypted_raw RAW(2048);
-- convert input to raw
encrypted_raw := dbms_crypto.Encrypt(
src => raw_input,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
15/91
Oracle 10g数据加密技术
♠ Oracle 10g支持数据加密 :
♠ 解密存储过程
raw_key RAW(128);
encrypted_raw RAW(2048);
decrypted_raw RAW(2048);
decrypted_raw := dbms_crypto.Decrypt(
src => encrypted_raw,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
raw_key RAW(128);
encrypted_raw RAW(2048);
decrypted_raw RAW(2048);
decrypted_raw := dbms_crypto.Decrypt(
src => encrypted_raw,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
16/91
内容提要
♠ Oracle 9i 数据加密技术
♠ Oracle10g 加密包
♠ Oracle10g TDE 加密技术
♠ Oracle10g TDE 内置包
♠ Oracle11g TDE 技术
♠ 附录:样例
♠ 参考资源
17/91
数据安全与数据加密
♠ 数据安全存在漏洞:
♠ 数据库的备份磁带 可被带出数据中心
♠ 带走的磁带数据可轻松被恢复和浏览
♠ 如何保护你的数据库以防止这种漏洞
♠ 解决数据安全早期方法:
♠ 数据库中将敏感数据加密,再将加密密钥存储在一个不同的地方,这样即使数据被盗也是没有用的
♠ 数据加密与密钥的矛盾 :
应用程序访问加密密钥的方便性、防止密钥被盗的安全性
18/91
10g 数据加密
♠ 10g R2 透明数据加密(Transparent Data Encryption,TDE ):
♠ 不写一行代码,只需要声明你需要加密某列
♠ 当用户插入数据的时候,数据库透明的加密数据然后存储加密后的数据。
♠ 当用户读取数据时,数据库自动进行解密。不需要应用程序修改代码,因此叫做:透明数据加密
♠ 使用10g R2数据库和TDE
♠ 定义需要加密的列,Oracle 将为包含加密列的表创建一个私密安全加密密钥,然后采用你指定的加密算法加密指定列的明文数据
♠ 保护表的加密密钥(以下称“表密钥”)就显得非常重要了。Oracle 10g通过一个master密钥来对表密钥进行加密。master密钥保存在一个叫做“钱夹(wallet)”的安全的地方,钱夹可以是数据库服务器上的一个文件,加密的表密钥保存在数据字典中。
10g 透明数据加密
SQL request
Table key applied
Decrypted data
20/91
10g R2数据加密
♠ 10g R2数据加密工作原理: ♠ 当用户插入数据到需要加密的列中的时候,Oracle 10g从钱夹中获
取master密钥,用master密钥解密数据字典中的表密钥,然后用解密后的表密钥加密输入数据,再将加密后的数据保存在数据库中
♠ TDE工作原理如下图:
21/91
10g R2数据加密
♠ 10g R2 TDE加密与存储 :
♠ 加密表的部分或者所有列
♠ 无论是单个列或多个列加密,Oracle只会生成一个表级的加密密钥,然后用这个密钥加密所有的加密列
♠ 由于数据是加密存储的,所有后续的组建(如备份和归档日志,都是加密的格式) 都是自动加密
♠ 10g R2 TDE查询与解密 :
♠ 当查询一个加密列时,Oracle 将加密的表密钥从数据字典中取出,再取出master密钥,然后解密表密钥,再用解密后的表密钥来解密磁盘上加密的数据,最后返回明文给用户
22/91
10g R2数据加密
♠ 10g R2 TDE 工作流程:
♠ TDE对表数据加密与解密:
23/91
10g R2数据加密
♠ 10g R2 TDE的好处 :
♠ 通过这种加密数据的方式,即使保存在磁盘上的数据被盗,由于master密钥并没有被盗,没有master密钥的情况下,数据无法被获取
♠ 即使“钱夹(wallet)”被盗,如果没有钱夹密码(注:TDE涉及3个密码,一个是钱夹密码,用来启动钱夹;一个是master密钥,用来加解密表密钥;一个是表密钥,用来加解密数据,钱夹密码是用户手工输入的,master
密钥和表密钥是系统管理的),master密钥还是无法获取。
24/91
内容提要
♠ Oracle 9i 数据加密技术
♠ Oracle10g TDE 技术
♠ 使用Oracle10g TDE 加密表
♠ 使用Oracle10g TDE 内置包
♠ Oracle11g TDE 技术
♠ 附录:样例
♠ 参考资源
25/91
创建主键( Master Key)
sqlnet.ora
Wallet location
Master key
Key table
26/91
创建Wallet过程
♠ 创建钱夹(Wallet)过程 :
♠ 1.确认Oracle 软件目录和Wallet可访问目录
♠ 2.在sqlnet.ora文件中加入
♠ 3. lsnrctl start
♠ 4. sqlplus /as sysdba
♠ 5. SQL> ALTER SYSTEM SET ENCRYPTION KEY
IDENTIFIED BY "welcome1";
$ORACLE_HOME/network/admin/sqlnet.ora:
ENCRYPTION_WALLET_LOCATION=
(SOURCE=(METHOD=FILE)(METHOD_DATA=
(DIRECTORY=/u01/app/oracle/product/10.2.0/db_1/wallet)))
$ORACLE_HOME/network/admin/sqlnet.ora:
ENCRYPTION_WALLET_LOCATION=
(SOURCE=(METHOD=FILE)(METHOD_DATA=
(DIRECTORY=/u01/app/oracle/product/10.2.0/db_1/wallet)))
27/91
使用10g R2 TDE
♠ 使用 TDE步骤 :
♠ 由于默认安装下,TDE没有被启用,所以首次使用要进行必要的准备工作
♠ 第一次使用TDE时:
1)指定“钱夹”的位置
2)设置钱夹密码
3)打开钱夹
28/91
使用10g R2 TDE-准备
♠ 1.指定钱夹位置 :
♠ 默认下,钱夹创建于$ORACLE_BASE/admin/$ORACLE_SID/wallet
目录下
♠ 如果$ORACLE_BASE是/u01/app/oracle且$ORACLE_SID是SWBT4,则钱夹将存储在/u01/app/oracle/admin/SWBT4/wallet目录下
♠ 在sqlnet.ora文件增加加密参数 :
钱夹放在/orawall目录下 ,则
#在sqlnet.ora文件
ENCRYPTION_WALLET_LOCATION =
(SOURCE=
(METHOD=file)
(METHOD_DATA=
(DIRECTORY=/orawall)))
#在sqlnet.ora文件
ENCRYPTION_WALLET_LOCATION =
(SOURCE=
(METHOD=file)
(METHOD_DATA=
(DIRECTORY=/orawall)))
29/91
使用10g R2 TDE-准备
♠ 2.创建钱夹 :
♠ 必须创建钱夹,而且必须设定访问密码。为了能够完成此操作,通过如下的操作给一个用户赋予特权(privilege):
♠ 这条命令完成如下功能:
在步骤1中指定的目录下创建了一个钱夹
设定了钱夹的密码为“remnant”
打开了用于TDE存储和获取master密钥的钱夹
♠ 钱夹密码是大小写敏感的且必须用双引号括起来。密码“remnant”在任何动态性能视图或者日志中都不会显示为明文
alter system set encryption key
authenticated by "remnant";
alter system set encryption key
authenticated by "remnant";
30/91
使用10g R2 TDE-准备
♠ 3.打开钱夹 :
♠ 由于钱夹只需要创建一次,因此上面的两个步骤只需要执行一次。钱夹必须显式的在数据库启动后打开。当你创建钱夹的同时钱夹也被打开了。当创建钱夹且设定密码后,每次打开数据库的时候,你都必须使用密码按照如下方式打开钱夹 :
♠ 如果钱夹被关闭,你还是可以访问没有加密的列,但不能够访问加密的列
♠ 可以通过如下方式关闭钱夹:
为了TDE能够正常工作,钱夹必须被打开 ,不用时才关闭
alter system set encryption wallet
open authenticated by "remnant";
alter system set encryption wallet
open authenticated by "remnant";
alter system set encryption wallet close; alter system set encryption wallet close;
31/91
使用10g R2 TDE-加密列
♠ 指定列加密 :
♠ 希望对表的列加密,使用谓词“ENCRYPT 即可:
CREATE TABLE或ALTER TABLE均可用
-- 创建表时指定列加密语法
CREATE TABLE table_name ( column_name column_type
ENCRYPT,....);
--修改表时指定列加密语法
ALTER TABLE table_name MODIFY ( column_name
column_type ENCRYPT,...);
-- 创建表时指定列加密语法
CREATE TABLE table_name ( column_name column_type
ENCRYPT,....);
--修改表时指定列加密语法
ALTER TABLE table_name MODIFY ( column_name
column_type ENCRYPT,...);
32/91
使用10g R2 TDE-加密列
♠ 指定列加密 :
♠ 希望对表的列加密,使用谓词“ENCRYPT 即可:
CREATE TABLE时指定列加密
--创建表时指定列加密语法
CREATE TABLE employee (
first_name VARCHAR2(128),
last_name VARCHAR2(128),
empID NUMBER,
salary NUMBER(6) ENCRYPT
);
--创建表时指定列加密语法
CREATE TABLE employee (
first_name VARCHAR2(128),
last_name VARCHAR2(128),
empID NUMBER,
salary NUMBER(6) ENCRYPT
);
33/91
使用10g R2 TDE-加密列
♠ 指定列加密
♠ 对外部表的加密方法:
--创建表时指定列加密语法
Example 3–7 Creating a New External Table with a Password-Generated Column
Key
CREATE TABLE emp_ext (
first_name,
last_name,
empID,
salary,
ssn ENCRYPT IDENTIFIED BY "xIcf3T9u"
) ORGANIZATION EXTERNAL
(
TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY "D_DIR"
LOCATION(’emp_ext.dat’)
)
REJECT LIMIT UNLIMITED
as select * from employee;
--创建表时指定列加密语法
Example 3–7 Creating a New External Table with a Password-Generated Column
Key
CREATE TABLE emp_ext (
first_name,
last_name,
empID,
salary,
ssn ENCRYPT IDENTIFIED BY "xIcf3T9u"
) ORGANIZATION EXTERNAL
(
TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY "D_DIR"
LOCATION(’emp_ext.dat’)
)
REJECT LIMIT UNLIMITED
as select * from employee;
34/91
使用10g R2 TDE-加密列
♠ 关于SALT(加盐) :
♠ 如果原始的明文数据有很多重复的数据时,有时很容易能够猜出加密数据的原始值
♠ 将“salt”加入到数据中使得即使原始值相同的数据加密后具有不同的加密值
♠ TDE缺省情况下应用了“salt”技术
♠ 在列上使用salt加密后,则该列不能创建作用索引,否则提示:ORA-28338: cannot encrypt indexed column(s) with salt
35/91
使用10g R2 TDE-加密列
♠ 指定列加密 :
♠ 对表的列加密不指定SALT,以便创建索引:
--创建表时指定列加密为 NO SALT
CREATE TABLE employee (
first_name VARCHAR2(128),
last_name VARCHAR2(128),
empID NUMBER ENCRYPT NO SALT,
salary NUMBER(6) ENCRYPT USING ’3DES168’
);
CREATE INDEX employee_idx on employee (empID);
--创建表时指定列加密为 NO SALT
CREATE TABLE employee (
first_name VARCHAR2(128),
last_name VARCHAR2(128),
empID NUMBER ENCRYPT NO SALT,
salary NUMBER(6) ENCRYPT USING ’3DES168’
);
CREATE INDEX employee_idx on employee (empID);
36/91
使用10g R2 TDE-加密列
♠ 指定列加密 :
♠ 对表的列加密指定SALT
--修改表时指定列加密带SALT
--Example 3–3 Adding Salt to an Encrypted Column
ALTER TABLE employee MODIFY (first_name ENCRYPT SALT);
--Example 3–4 Removing Salt from an Encrypted Column
ALTER TABLE employee MODIFY (first_name ENCRYPT NO SALT);
--修改表时指定列加密带SALT
--Example 3–3 Adding Salt to an Encrypted Column
ALTER TABLE employee MODIFY (first_name ENCRYPT SALT);
--Example 3–4 Removing Salt from an Encrypted Column
ALTER TABLE employee MODIFY (first_name ENCRYPT NO SALT);
37/91
使用10g R2 TDE-加密列
♠ 指定列加密 :
♠ 指定表的列加密算法3DES168
--创建表时指定列加密带NO SALT
--
CREATE TABLE employee (
first_name VARCHAR2(128),
last_name VARCHAR2(128),
empID NUMBER ENCRYPT NO SALT,
salary NUMBER(6) ENCRYPT USING ’3DES168’
);
--创建表时指定列加密带NO SALT
--
CREATE TABLE employee (
first_name VARCHAR2(128),
last_name VARCHAR2(128),
empID NUMBER ENCRYPT NO SALT,
salary NUMBER(6) ENCRYPT USING ’3DES168’
);
38/91
使用10g R2 TDE-加密列
♠ 指定列加密不加盐以便创建索引 :
♠ 指定表的列为 NO SALT
--创建表时指定列加密带NO SALT
--
Alter table credit_rating modify
(person_id encrypt no salt);
--
Create index person_id_idx on credit_rating (PERSON_ID);
--
Select score from credit_rating where
PERSON_ID='235901';
--创建表时指定列加密带NO SALT
--
Alter table credit_rating modify
(person_id encrypt no salt);
--
Create index person_id_idx on credit_rating (PERSON_ID);
--
Select score from credit_rating where
PERSON_ID='235901';
数据用法保持原来模样
在加密的列上创建索引
加密的列为NO Salt
39/91
使用10g R2 TDE-加密列
♠ 指定列加密10g默认情况 :
♠ 默认下表的列为 AES 192 bit:
--创建表时指定列加密
alter table credit_rating modify (person_id encrypt);
--建议指定明确的加密算法,如:
create table employee (
first_name varchar2(64),
last_name varchar2(64),
empID NUMBER encrypt using 'AES256',
salary NUMBER(6) encrypt using 'AES256');
--
--创建表时指定列加密
alter table credit_rating modify (person_id encrypt);
--建议指定明确的加密算法,如:
create table employee (
first_name varchar2(64),
last_name varchar2(64),
empID NUMBER encrypt using 'AES256',
salary NUMBER(6) encrypt using 'AES256');
--
在加密的列上指定算法
默认列加密AES 192 Bit
40/91
使用10g R2 TDE-加密列
♠ 修改表加密算法 :
♠ 指定表的加密算法:
--指定表列加密-还要用原来的加密算法:
ALTER TABLE employee REKEY;
--指定表的加密算法改为AES256:
ALTER TABLE employee REKEY USING 'AES256';
--指定表的加密为 AES128:
ALTER TABLE employee ENCRYPT USING 'AES128';
--指定表列加密-还要用原来的加密算法:
ALTER TABLE employee REKEY;
--指定表的加密算法改为AES256:
ALTER TABLE employee REKEY USING 'AES256';
--指定表的加密为 AES128:
ALTER TABLE employee ENCRYPT USING 'AES128';
41/91
使用10g R2 TDE-性能考虑
♠ 列加密与性能的平衡
♠ 由于加解密消耗CPU,因此你必须考虑性能的影响。
♠ 当访问表中不加密的列时,性能和不使用TDE的表没有任何差别
♠ 当在访问加密列的时候,会有小的性能负担,包括查询加密列和插入加密列,因此你也许想有选择的加密列
♠ 如果你不再需要对一个列加密,你可以通过如下方式关闭加密功能:
--修改表时指定列为不加密-decrypt
alter table account modify (ssn decrypt);
--修改表时指定列为不加密-decrypt
alter table account modify (ssn decrypt);
42/91
使用10g R2 TDE-维护密钥
♠ 管理表的密钥
♠ 怀疑某人可能已经破解了加密的表密钥,简单的为表创建一个新的密钥
♠ 也可选择另外一个算法进行加密,例如使用 ’3DES168’ :
--修改表密钥
ALTER TABLE employee REKEY;
--修改表使用另外的密钥:
ALTER TABLE employee REKEY USING ’3DES168’;
--修改表密钥
ALTER TABLE employee REKEY;
--修改表使用另外的密钥:
ALTER TABLE employee REKEY USING ’3DES168’;
43/91
使用10g R2 TDE-维护钱夹
♠ 管理钱夹(Wallet)
♠ 怀疑某人得到了钱夹的密码,可以通过Oracle Wallet
Manager修改钱夹密码
♠ 在命令行中输入OWM即可调用如下GUI工具。从顶上的菜单选择Wallet -> Open并且选择你指定的钱夹的位置,然后给出钱夹密码,选择Wallet -> Change
Password修改钱夹密码。
♠ 需要说明的是修改钱夹的密码不会修改master密钥 :
44/91
使用10g R2 TDE-维护钱夹
♠ 管理钱夹 ♠ GUI工具-10g Wallet Manager 界面 :
45/91
使用10g R2 TDE-导出TDE
♠ TDE 密钥可与实用程序一起使用
♠ 默认情况下,如果使用EXPDP工具导出一个拥有加密列的表,在导出文件(dump file)中列是明文的,即使列定义为加密也是如此。如下命令导出ACCOUNTS表(包括加密的列),将会返回一个警告:
♠ 这只是一个警告,不是错误,数据还是会被导出
$ expdp arup/arup tables=accounts
ORA-39173: Encrypted data has been stored
unencrypted in dump file set.
$ expdp arup/arup tables=accounts
ORA-39173: Encrypted data has been stored
unencrypted in dump file set.
46/91
使用10g R2 TDE-导出TDE
♠ TDE 密钥可与实用程序一起使用 ♠ 为了在数据导出文件中保护你的加密的列数据,你可以在导出表的
时候通过密码保护机制来保护导出文件
♠ 这个密码通过在EXPDP命令中的ENCRYPTION_PASSWORD参数指定,且只会应用到本次导出,这个不是“钱夹”的密码
♠ 下面清单1中的密码并不会显示为“pooh”,而是通过*号来隐藏
$ expdp arup/arup ENCRYPTION_PASSWORD=pooh tables=accounts
Export: Release 10.2.0.0.0 - Beta on Friday, 01 July, 2005 16:14:06
Copyright (c) 2003, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.0.0 - Beta
With the Partitioning, OLAP and Data Mining options
Starting "ARUP"."SYS_EXPORT_TABLE_01": arup/********
ENCRYPTION_PASSWORD=********* tables=accounts
Estimate in progress using BLOCKS method...
Processing ...
$ expdp arup/arup ENCRYPTION_PASSWORD=pooh tables=accounts
Export: Release 10.2.0.0.0 - Beta on Friday, 01 July, 2005 16:14:06
Copyright (c) 2003, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.0.0 - Beta
With the Partitioning, OLAP and Data Mining options
Starting "ARUP"."SYS_EXPORT_TABLE_01": arup/********
ENCRYPTION_PASSWORD=********* tables=accounts
Estimate in progress using BLOCKS method...
Processing ...
47/91
使用10g R2 TDE-导出TDE
♠ TDE 密钥可与实用程序一起使用
♠ 当你导入加密的dump文件时,你也必须提供同样的密码,代码清单2显示了如何操作:
$ impdp arup/arup ENCRYPTION_PASSWORD=pooh tables=accounts
table_exists_action=replace
Import: Release 10.2.0.0.0 - Beta on Friday, 01 July, 2005 16:04:20
Copyright (c) 2003, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.0.0 - Beta
With the Partitioning, OLAP and Data Mining options
Master table "ARUP"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "ARUP"."SYS_IMPORT_TABLE_01": arup/********
ENCRYPTION_PASSWORD=********* table_exists_action=replace
Processing ...
$ impdp arup/arup ENCRYPTION_PASSWORD=pooh tables=accounts
table_exists_action=replace
Import: Release 10.2.0.0.0 - Beta on Friday, 01 July, 2005 16:04:20
Copyright (c) 2003, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.0.0 - Beta
With the Partitioning, OLAP and Data Mining options
Master table "ARUP"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "ARUP"."SYS_IMPORT_TABLE_01": arup/********
ENCRYPTION_PASSWORD=********* table_exists_action=replace
Processing ...
48/91
使用10g R2 TDE-数据卫士环境
♠ TDE 在Data Guard环境自动应用到备用库中
♠ 10g/11g 自动通过日志实现对备用库的加密:
49/91
使用10g R2 TDE-限制
♠ TDE 支持的数据类型: ♠ varchar2
♠ nvarchar2
♠ number
♠ date
♠ binary_float (*)
♠ binary_double (*)
♠ timestamp
♠ raw
♠ char
♠ nchar
♠ TDE 不支持的功能: ♠ Materialized View logs
♠ Streams
♠ Sync and async CDC
♠ Direct path insert
♠ Transportable Tablespaces
♠ LOBs
50/91
内容提要
♠ Oracle 9i 数据加密技术
♠ Oracle10g TDE 技术
♠ 使用Oracle10g TDE 加密表
♠ 使用Oracle10g TDE 内置包
♠ Oracle11g TDE 技术
♠ 附录:样例
♠ 参考资源
51/91
使用DBMS_CRYPTO
♠ DBMS_CRYPTO包
♠ 产生随机数键值
♠ 加密和解密列值
♠ 使用DBMS_CRYPTO包
♠ 加密表的列值
♠ 解密表的列值
♠ 支持9i版本的DBMS_OBFUSCATION_TOOLKIT
DBMS_CRYPTO
OKYMSEISPDTGA
MyCreditCardNum
CUST.CREDITCARD
52/91
使用DBMS_CRYPTO
♠ DBMS_CRYPTO与DBMS_OBFUSCATION_TOOLKIT包
♠ Oracle 10g/11g 推荐使用DBMS_CRYPTO
♠ 这两个包支持加密的差异
功能 DBMS_CRYPTO DBMS_OBFUSCATION_TO
OLKIT
密码算法 DES, 3DES, AES, RC4,
3DES_2KEY
DES, 3DES
数据库类型 RAW, CLOB, BLOB RAW, VARCHAR2
块密码链模式 CBC, CFB, ECB, OFB CBC
密码Hash算法 MD5, SHA-1, MD4 MD5
键值Hash算法(MAC) HMAC_MD5, HMAC_SH1 不支持
53/91
两加密包功能比较
包的特点 DBMS_CRYPTO
DBMS_OBFUSCATION_
TOOLKIT
加密算法 DES, 3DES, AES, RC4,
3DES_2KEY
DES, 3DES
填充形式(Padding forms) PKCS5, zeroes 无支持项
密码分组链接模式 (
Block cipher chaining
modes)
CBC, CFB, ECB, OFB CBC
加密散列算法
(Cryptographic hash
algorithms)
MD5, SHA-1, MD4 MD5
密钥散列 (MAC) 算法 HMAC_MD5,
HMAC_SH1
无支持项
加密伪随机数生成器 RAW, NUMBER,
BINARY_INTEGER RAW, VARCHAR2
数据库类型 RAW, CLOB, BLOB RAW, VARCHAR2
54/91
加密的挑战
♠ 译码的索引数据问题
♠ 密钥的管理问题
♠ 密钥的传输问题
♠ 密钥的存储问题
♠ 改变密钥问题
♠ 二进制对象问题 (BLOBS)
55/91
使用DBMS_CRYPTO包
♠ 产生随机数加密
♠ 1.产生随机数- 用RANDOMBYTES产生键值
♠ 2.用dbms_crypto.encrypt加密:
raw_key := dbms_crypto.randombytes (number_bytes => 24); raw_key := dbms_crypto.randombytes (number_bytes => 24);
encrypted_raw := dbms_crypto.encrypt (
src => raw_input,
typ => DBMS_CRYPTO.DES3_CBC_PKCS5
key => raw_key );
encrypted_raw := dbms_crypto.encrypt (
src => raw_input,
typ => DBMS_CRYPTO.DES3_CBC_PKCS5
key => raw_key );
56/91
使用DBMS_CRYPTO
♠ 产生随机数加密
♠ 1.用dbms_crypto.Encrypt函数加密
♠ 2.用DBMS_CRYPTO.Decrypt函数解密 :
encrypted_raw := dbms_crypto.Encrypt (
src => raw_input,
typ => dbms_crypto.DES3_CBC_PKCS5,
key => raw_key);
encrypted_raw := dbms_crypto.Encrypt (
src => raw_input,
typ => dbms_crypto.DES3_CBC_PKCS5,
key => raw_key);
decrypted_raw := dbms_crypto.Decrypt (
encrypted_raw,
dbms_crypto.DES3_CBC_PKCS5,
raw_key);
decrypted_raw := dbms_crypto.Decrypt (
encrypted_raw,
dbms_crypto.DES3_CBC_PKCS5,
raw_key);
57/91
使用DBMS_CRYPTO-样例0
♠ 确认DBMS_CRYPTO包已经安装
♠ 一般10g /11g RDBMS创建成功后都安装完毕,如:
SQL> select object_name from dba_objects
where object_name like 'DBMS_CRYPTO%'
OBJECT_NAME
-------------------------------------------------------------
DBMS_CRYPTO
DBMS_CRYPTO_FFI
DBMS_CRYPTO_FFI
DBMS_CRYPTO
DBMS_CRYPTO_TOOLKIT_TYPES
DBMS_CRYPTO_TOOLKIT
DBMS_CRYPTO_TOOLKIT_FFI
DBMS_CRYPTO_TOOLKIT_FFI
DBMS_CRYPTO_TOOLKIT
DBMS_CRYPTO
DBMS_CRYPTO_TOOLKIT
已选择11行。
SQL> select object_name from dba_objects
where object_name like 'DBMS_CRYPTO%'
OBJECT_NAME
-------------------------------------------------------------
DBMS_CRYPTO
DBMS_CRYPTO_FFI
DBMS_CRYPTO_FFI
DBMS_CRYPTO
DBMS_CRYPTO_TOOLKIT_TYPES
DBMS_CRYPTO_TOOLKIT
DBMS_CRYPTO_TOOLKIT_FFI
DBMS_CRYPTO_TOOLKIT_FFI
DBMS_CRYPTO_TOOLKIT
DBMS_CRYPTO
DBMS_CRYPTO_TOOLKIT
已选择11行。
58/91
使用DBMS_CRYPTO-样例0
♠ 使用DBMS_CRYPTO包
♠ 在匿名块中使用,如:
set serveroutput on
DECLARE
input_string VARCHAR2(16) := 'CreditCardNumber';
raw_input RAW(128) := UTL_I18N.STRING_TO_RAW(input_string,'AL32UTF8');
raw_key RAW(256);
encrypted_raw RAW(2048);
encrypted_string VARCHAR2(2048);
decrypted_raw RAW(2048);
decrypted_string VARCHAR2(2048);
BEGIN
dbms_output.put_line('> ========= Get Key Bytes =========');
raw_key := dbms_crypto.randombytes(24);
dbms_output.put_line('> Key String length: ' || UTL_RAW.LENGTH(raw_key));
dbms_output.put_line('> Key String: ' || UTL_RAW.CAST_TO_VARCHAR2(raw_key));
dbms_output.put_line('> Input String: ' || input_string);
dbms_output.put_line('> ========= BEGIN TEST Encrypt =========');
encrypted_raw := dbms_crypto.Encrypt(src => raw_input, typ => DBMS_CRYPTO.DES3_CBC_PKCS5, key => raw_key);
dbms_output.put_line('> Encrypted hex value : ' || rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('> Encrypted varchar2 value: ' || UTL_RAW.CAST_TO_VARCHAR2(encrypted_raw));
decrypted_raw := dbms_crypto.Decrypt(src => encrypted_raw, typ => DBMS_CRYPTO.DES3_CBC_PKCS5, key => raw_key);
decrypted_string := UTL_I18N.RAW_TO_CHAR(decrypted_raw,'AL32UTF8');
dbms_output.put_line('> Decrypted string output : ' ||decrypted_string);
if input_string = decrypted_string THEN
dbms_output.put_line('> String DES Encyption and Decryption successful');
END if;
END;
/
set serveroutput on
DECLARE
input_string VARCHAR2(16) := 'CreditCardNumber';
raw_input RAW(128) := UTL_I18N.STRING_TO_RAW(input_string,'AL32UTF8');
raw_key RAW(256);
encrypted_raw RAW(2048);
encrypted_string VARCHAR2(2048);
decrypted_raw RAW(2048);
decrypted_string VARCHAR2(2048);
BEGIN
dbms_output.put_line('> ========= Get Key Bytes =========');
raw_key := dbms_crypto.randombytes(24);
dbms_output.put_line('> Key String length: ' || UTL_RAW.LENGTH(raw_key));
dbms_output.put_line('> Key String: ' || UTL_RAW.CAST_TO_VARCHAR2(raw_key));
dbms_output.put_line('> Input String: ' || input_string);
dbms_output.put_line('> ========= BEGIN TEST Encrypt =========');
encrypted_raw := dbms_crypto.Encrypt(src => raw_input, typ => DBMS_CRYPTO.DES3_CBC_PKCS5, key => raw_key);
dbms_output.put_line('> Encrypted hex value : ' || rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('> Encrypted varchar2 value: ' || UTL_RAW.CAST_TO_VARCHAR2(encrypted_raw));
decrypted_raw := dbms_crypto.Decrypt(src => encrypted_raw, typ => DBMS_CRYPTO.DES3_CBC_PKCS5, key => raw_key);
decrypted_string := UTL_I18N.RAW_TO_CHAR(decrypted_raw,'AL32UTF8');
dbms_output.put_line('> Decrypted string output : ' ||decrypted_string);
if input_string = decrypted_string THEN
dbms_output.put_line('> String DES Encyption and Decryption successful');
END if;
END;
/
59/91
使用DBMS_CRYPTO-样例0
♠ 使用DBMS_CRYPTO包
♠ 在匿名块中使用,如:
> ========= Get Key Bytes =========
> Key String length: 24
> Key String: �鶩菭韖S�WF�F=輬,?趫
找
> Input String: CreditCardNumber
> ========= BEGIN TEST Encrypt =========
> Encrypted hex value :
3039464437313839443944303331413935394331443533314236383037453431374342
35424439353331444135354137
> Encrypted varchar2 value: 齫壻?℡琳1秬~A|到?赨
> Decrypted string output : CreditCardNumber
> String DES Encyption and Decryption successful
PL/SQL 过程已成功完成。
> ========= Get Key Bytes =========
> Key String length: 24
> Key String: �鶩菭韖S�WF�F=輬,?趫
找
> Input String: CreditCardNumber
> ========= BEGIN TEST Encrypt =========
> Encrypted hex value :
3039464437313839443944303331413935394331443533314236383037453431374342
35424439353331444135354137
> Encrypted varchar2 value: 齫壻?℡琳1秬~A|到?赨
> Decrypted string output : CreditCardNumber
> String DES Encyption and Decryption successful
PL/SQL 过程已成功完成。
60/91
使用DBMS_CRYPTO-样例1
♠ 在函数使用DBMS_CRYPTO包
♠ 1.编辑一个函数代码如下,并以crypt.sql文件存储
create or replace function des_crypt
(pv_text in varchar) return raw is
lv_key raw(128);
lv_text raw(2000);
begin
lv_text:=sys.utl_i18n.string_to_raw(
pv_text,'AL32UTF8');
lv_key :=sys.utl_i18n.string_to_raw(
sys.dbms_crypto.randombytes (16),'AL32UTF8');
return(sys.dbms_crypto.encrypt(
lv_text,sys.dbms_crypto.DES3_CBC_PKCS5,lv_key));
end des_crypt;
/
create or replace function des_crypt
(pv_text in varchar) return raw is
lv_key raw(128);
lv_text raw(2000);
begin
lv_text:=sys.utl_i18n.string_to_raw(
pv_text,'AL32UTF8');
lv_key :=sys.utl_i18n.string_to_raw(
sys.dbms_crypto.randombytes (16),'AL32UTF8');
return(sys.dbms_crypto.encrypt(
lv_text,sys.dbms_crypto.DES3_CBC_PKCS5,lv_key));
end des_crypt;
/
61/91
使用DBMS_CRYPTO-样例1
♠ 在函数使用DBMS_CRYPTO包
♠ 2.在SQL>下运行crypt.sql脚本
♠ 看到Crypted text被加密成乱码如下:
SQL> @crypt
Function created.
SQL> set serveroutput on size 1000000
SQL> exec dbms_output.put_line('Crypted text:
'||des_crypt('test crypt'));
Crypted text:
8640FE54ED48429423E5EABB01AA3334
SQL> @crypt
Function created.
SQL> set serveroutput on size 1000000
SQL> exec dbms_output.put_line('Crypted text:
'||des_crypt('test crypt'));
Crypted text:
8640FE54ED48429423E5EABB01AA3334
62/91
使用DBMS_CRYPTO-样例2
♠ 创建样例表 cust_payment_info
♠ 创建表与插入数据:
CREATE TABLE cust_payment_info
(first_name VARCHAR2(11),
last_name VARCHAR2(10),
order_number NUMBER(5),
credit_card_number VARCHAR2(16) ENCRYPT NO SALT,
active_card VARCHAR2(3));
CREATE TABLE cust_payment_info
(first_name VARCHAR2(11),
last_name VARCHAR2(10),
order_number NUMBER(5),
credit_card_number VARCHAR2(16) ENCRYPT NO SALT,
active_card VARCHAR2(3));
INSERT INTO cust_payment_info VALUES
('Jon', 'Oldfield', 10001, '5446959708812985','YES');
INSERT INTO cust_payment_info VALUES
('Chris', 'White', 10002, '5122358046082560','YES');
INSERT INTO cust_payment_info VALUES
('Alan', 'Squire', 10003, '5595968943757920','YES');
INSERT INTO cust_payment_info VALUES
('Mike', 'Anderson', 10004, '4929889576357400','YES');
INSERT INTO cust_payment_info VALUES
('Annie', 'Schmidt', 10005, '4556988708236902','YES');
INSERT INTO cust_payment_info VALUES
('Elliott', 'Meyer', 10006, '374366599711820','YES');
INSERT INTO cust_payment_info VALUES
('Celine', 'Smith', 10007, '4716898533036','YES');
INSERT INTO cust_payment_info VALUES
('Steve', 'Haslam', 10008, '340975900376858','YES');
INSERT INTO cust_payment_info VALUES
('Albert', 'Einstein', 10009, '310654305412389','YES');
INSERT INTO cust_payment_info VALUES
('Jon', 'Oldfield', 10001, '5446959708812985','YES');
INSERT INTO cust_payment_info VALUES
('Chris', 'White', 10002, '5122358046082560','YES');
INSERT INTO cust_payment_info VALUES
('Alan', 'Squire', 10003, '5595968943757920','YES');
INSERT INTO cust_payment_info VALUES
('Mike', 'Anderson', 10004, '4929889576357400','YES');
INSERT INTO cust_payment_info VALUES
('Annie', 'Schmidt', 10005, '4556988708236902','YES');
INSERT INTO cust_payment_info VALUES
('Elliott', 'Meyer', 10006, '374366599711820','YES');
INSERT INTO cust_payment_info VALUES
('Celine', 'Smith', 10007, '4716898533036','YES');
INSERT INTO cust_payment_info VALUES
('Steve', 'Haslam', 10008, '340975900376858','YES');
INSERT INTO cust_payment_info VALUES
('Albert', 'Einstein', 10009, '310654305412389','YES');
63/91
加密相关数据字典
♠ 加密有关数据字典有: ♠ DBA_ENCRYPTED_COLUMNS
♠ USER_ENCRYPTED_COLUMNS
♠ ALL_ENCRYPTED_COLUMNS
♠ V$RMAN_ENCRYPTION_ALGORITHMS
♠ V$ENCRYPTED_TABLESPACES
♠ V$ENCRYPTION_WALLET
64/91
加密相关数据字典
♠ DBA_ENCRYPTED_COLUMNS ♠ ENCRYPTION_ALG VARCHAR2(29—加密算法,分别是:
♠ AES 128 bits key
♠ AES 192 bits key
♠ AES 256 bits key
♠ ENCRYPTION_ALG VARCHAR2(29—加密算法,分别是:
♠ AES 128 bits key
♠ SALT VARCHAR2(3)—是否加盐
♠ INTEGRITY_ALG VARCHAR2(12)—整数算法:SHA-1与NOMAC
65/91
加密相关数据字典
♠ DBA_ENCRYPTED_COLUMNS
♠ 查询加密列的信息:
SQL> select table_name, column_name, encryption_alg
2 from dba_encrypted_columns
3 /
TABLE_NAME COLUMN_NAME ENCRYPTION_ALG
------------------------------ ------------------ -----------------------------
CONTRACTS_SEC ORIG_FILE AES 128 bits key
SQL> select table_name, column_name, encryption_alg
2 from dba_encrypted_columns
3 /
TABLE_NAME COLUMN_NAME ENCRYPTION_ALG
------------------------------ ------------------ -----------------------------
CONTRACTS_SEC ORIG_FILE AES 128 bits key
66/91
加密相关数据字典
♠ V$ENCRYPTED_TABLESPACES-11g ♠ TS# NUMBER
♠ ENCRYPTIONALG VARCHAR2(7):
♠ NONE
♠ 3DES168
♠ AES128
♠ AES192
♠ AES256
♠ ENCRYPTEDTS VARCHAR2(3)
SQL> desc v$encrypted_tablespaces
Name Null?Type
----------------------------------------- -------- ------------
TS# NUMBER
ENCRYPTIONALG VARCHAR2(7)
ENCRYPTEDTS VARCHAR2(3)
SQL> select * from v$encrypted_tablespaces;
TS# ENCRYPT ENC
---------- ------- ---
5 AES128 YES
SQL> desc v$encrypted_tablespaces
Name Null?Type
----------------------------------------- -------- ------------
TS# NUMBER
ENCRYPTIONALG VARCHAR2(7)
ENCRYPTEDTS VARCHAR2(3)
SQL> select * from v$encrypted_tablespaces;
TS# ENCRYPT ENC
---------- ------- ---
5 AES128 YES
67/91
加密相关数据字典
♠ V$WALLET ♠ CERT_ID VARCHAR2(52)
♠ DN VARCHAR2(255)
♠ SERIAL_NUM VARCHAR2(40)
♠ ISSUER VARCHAR2(255)
♠ KEYSIZE NUMBER
♠ STATUS VARCHAR2(16)
♠ UNUSED
♠ IN USE
♠ USED
SQL> SQL>
68/91
加密相关数据字典
♠ V$ENCRYPTION_WALLET ♠ WRL_TYPE VARCHAR2(20)
♠ WRL_PARAMETER VARCHAR2(4000)
♠ STATUS VARCHAR2(9)
♠ OPEN
♠ CLOSED
♠ UNDEFINED
♠ OPEN_NO_MASTER_KEY
SQL> SQL>
69/91
内容提要
♠ Oracle 9i 数据加密技术
♠ Oracle10g TDE 技术
♠ 使用Oracle10g TDE 加密表
♠ 使用Oracle10g TDE 内置包
♠ Oracle11g TDE 技术
♠ 附录:样例
♠ 参考资源
70/91
Oracle 系统加密回顾
♠ 数据加密选项…
♠ DBMS_OBFUSCATION_TOOLKIT
♠ 8i-9iR2
♠ 今后不再使用
♠ 本次前面做了简要介绍,但是不推荐
♠ 建议开发人员直接了解下面的新包
♠ DBMS_CRYPTO
♠ 10gR1 及更高版本
♠ 不是必须使用 (because of the next two bullets)
♠ 前面已经简要介绍,下面只介绍差异的部分
♠ 列级的加密 ♠ 10gR2及更高版本(ASO)
♠ 表空间加密 ♠ 11gR1及更高版本(ASO)
71/91
列加密的限制
♠现在还存在限制
♠如果使用索引,则不能使用 ‘salt’
♠外部键不可使用
♠ exp/imp 问题 (清除文本)
♠ 11g-datapump 可处理加密问题.
72/91
表空间级加密
♠ 磁盘存储加密
♠ 数据缓存在SGA中不加密
♠ 撤销数据加密
♠ 日期数据加密
♠ 数据在块中以明文存储与离开磁盘解密
♠ 索引是以明文存在的
♠ 范围扫描 – 解答
♠ 外部键 –解答
73/91
表空间级加密
♠ 11g 版本支持表空间数据加密
♠例1:指定加密算法为AES128:
create tablespace secure1
datafile '/db1/1.dbf' size 1M
encryption using 'AES128'
default storage (encrypt)
--
SQL> desc v$encrypted_tablespaces
Name Null? Type
----------------- -------- -----------
TS# NUMBER
ENCRYPTIONALG VARCHAR2(7)
ENCRYPTEDTS VARCHAR2(3)
74/91
表空间级加密
♠ 11g 版本支持表空间数据加密
♠例2:指定加密算法为AES256:
CREATE TABLESPACE securespace
DATAFILE 'c:\temp\secure02.dbf' SIZE 25M
ENCRYPTION USING 'AES256'
DEFAULT STORAGE(ENCRYPT);
SQL> SELECT ta.table_name, ts.tablespace_name, ts.encrypted
2 FROM user_tables ta, user_tablespaces ts
3 WHERE ta.tablespace_name = ts.tablespace_name
4 ORDER BY 2, 1;
TABLE_NAME TABLESPACE_NAME ENC
------------------------------ ------------------------------ ---
T1 SECURESPACE YES
T2 SECURESPACE2 YES
AIRPLANES UWDATA NO
SERVERS UWDATA NO
SERV_INST UWDATA NO
75/91
数据加密与性能
♠数据加密对性能有些影响
♠不同版本加密影响程度不同:
76/91
安全文件-加密
♠ 11g 版本支持文件级的数据安全-加密
♠例1:指定文件安全-加密:
SQL> SELECT name, value
2 FROM gv$parameter
3 WHERE name LIKE '%secure%';
NAME VALUE
------------------------------ ---------
db_securefile PERMITTED
optimizer_secure_view_merging TRUE
CREATE TABLE sec_tab2 (
rid NUMBER(5),
bcol BLOB)
LOB (bcol)
STORE AS SECUREFILE bcol2 (
TABLESPACE securefiletbs
RETENTION MIN 3600 COMPRESS ENCRYPT CACHE READS)
TABLESPACE uwdata;
77/91
数据的屏蔽-data mask
♠ 11g 版本新推出数据屏蔽
♠关键的数据采用屏蔽,方法如:
78/91
数据的屏蔽-data mask
♠ 11g :EM-定义数据屏蔽:
♠定义数据屏蔽:
79/91
数据的屏蔽-data mask
♠ 11g :EM-定义数据屏蔽:
♠定义数据屏蔽:
80/91
数据的屏蔽-data mask
♠ 11g :EM-定义数据屏蔽:
♠数据屏蔽主要步骤:
81/91
数据的屏蔽-data mask
♠ 11g :EM-定义数据屏蔽:
♠数据屏蔽主要步骤:
82/91
内容提要
♠ Oracle 9i 数据加密技术
♠ Oracle10g TDE 技术
♠ 使用Oracle10g TDE 加密表
♠ 使用Oracle10g TDE 内置包
♠ Oracle11g TDE 技术
♠ 附录:样例
♠ 参考资源
83/91
EXP 与 加密
♠ 11g : EXP 带数据加密:
♠使用时提示:
exp enc_test/manager file=test.dmp tables=test_enc
...
EXP-00111: Table TEST_ENC resides in an Encrypted
Tablespace ENC_TEST and will not be exported
...
exp enc_test/manager file=test.dmp tables=test_enc
...
EXP-00111: Table TEST_ENC resides in an Encrypted
Tablespace ENC_TEST and will not be exported
...
84/91
11g 本地加密设置
♠ 11g 本地加密:
♠Orapki 实用程序:
orapki wallet create -wallet <wallet_location> \
-auto_login_local
orapki wallet create -wallet <wallet_location> \
-auto_login_local
85/91
附录1:DBMS_OBFUSCATION_TOOLKIT样例
♠ 9i 用DBMS_OBFUSCATION_TOOLKIT包:
♠ 9i 用DBMS_OBFUSCATION_TOOLKIT包实现数据加密
♠ 加密的PL/SQL 方法如下(B14258.pdf): DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input IN RAW,
key IN RAW,
decrypted_data OUT RAW,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv IN RAW DEFAULT NULL);
DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input_string IN VARCHAR2,
key_string IN VARCHAR2,
decrypted_string OUT VARCHAR2,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv_string IN VARCHAR2 DEFAUTL NULL);
DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input IN RAW,
key IN RAW,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv IN RAW DEFAULT NULL)
RETURN RAW;
DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input_string IN VARCHAR2,
key_string IN VARCHAR2,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv_string IN VARCHAR2 DEFAULT NULL)
RETURN VARCHAR2;
DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input IN RAW,
key IN RAW,
decrypted_data OUT RAW,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv IN RAW DEFAULT NULL);
DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input_string IN VARCHAR2,
key_string IN VARCHAR2,
decrypted_string OUT VARCHAR2,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv_string IN VARCHAR2 DEFAUTL NULL);
DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input IN RAW,
key IN RAW,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv IN RAW DEFAULT NULL)
RETURN RAW;
DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
input_string IN VARCHAR2,
key_string IN VARCHAR2,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv_string IN VARCHAR2 DEFAULT NULL)
RETURN VARCHAR2;
86/91
附录2:DBMS_CRYPTO包的使用
♠ 10g/11g用dbms_crypto实现加密解密:
♠ PL/SQL 方法- CRYPT_PKG来实现数据的加密解密: CREATE OR REPLACE PACKAGE crypt_pkg IS
typ PLS_INTEGER :=DBMS_CRYPTO.ENCRYPT_AES256
+DBMS_CRYPTO.CHAIN_CBC
+DBMS_CRYPTO.PAD_PKCS5;
key CONSTANT RAW(32) :='AB45456E59EFD93F63'||
'01F47DEE4BAF39A0234573400579DC5801A8AC2382BF6E';
FUNCTION encry(input RAW) RETURN RAW;
FUNCTION decry(encry_str RAW) RETURN RAW;
END;
/
CREATE OR REPLACE PACKAGE BODY crypt_pkg IS
FUNCTION encry(input RAW) RETURN RAW IS
BEGIN
RETURN dbms_crypto.encrypt(input,typ,key);
END;
FUNCTION decry(encry_str RAW ) RETURN RAW IS
BEGIN
RETURN dbms_crypto.decrypt(encry_str,typ,key);
END;
END;
/
CREATE OR REPLACE PACKAGE crypt_pkg IS
typ PLS_INTEGER :=DBMS_CRYPTO.ENCRYPT_AES256
+DBMS_CRYPTO.CHAIN_CBC
+DBMS_CRYPTO.PAD_PKCS5;
key CONSTANT RAW(32) :='AB45456E59EFD93F63'||
'01F47DEE4BAF39A0234573400579DC5801A8AC2382BF6E';
FUNCTION encry(input RAW) RETURN RAW;
FUNCTION decry(encry_str RAW) RETURN RAW;
END;
/
CREATE OR REPLACE PACKAGE BODY crypt_pkg IS
FUNCTION encry(input RAW) RETURN RAW IS
BEGIN
RETURN dbms_crypto.encrypt(input,typ,key);
END;
FUNCTION decry(encry_str RAW ) RETURN RAW IS
BEGIN
RETURN dbms_crypto.decrypt(encry_str,typ,key);
END;
END;
/
select crypt_pkg.encry(utl_i18n.string_to_raw('hello serapy ! ')) 加密
FROM dual;
加密
--------------------------------------------------------------------------------
E004CD9F40933241D66B39FC281526AF
select
utl_i18n.raw_to_char(crypt_pkg.decry(‘E004CD9F40933241D66B39FC281
526AF’)) 解密
FROM dual;
解密
--------------------------------------------------------------------------------
hello serapy !
SQL> spool off;
select crypt_pkg.encry(utl_i18n.string_to_raw('hello serapy ! ')) 加密
FROM dual;
加密
--------------------------------------------------------------------------------
E004CD9F40933241D66B39FC281526AF
select
utl_i18n.raw_to_char(crypt_pkg.decry(‘E004CD9F40933241D66B39FC281
526AF’)) 解密
FROM dual;
解密
--------------------------------------------------------------------------------
hello serapy !
SQL> spool off;
87/91
附录3:DBMS_CRYPTO包样例
♠ 用dbms_crypto-11g:
♠ PL/SQL 方法 : DECLARE
input_string VARCHAR2(16) := 'tigertigertigert';
raw_input RAW(128) :=
UTL_RAW.CAST_TO_RAW(CONVERT(input_string,'AL32UTF8','US7ASCII'));
key_string VARCHAR2(8) := 'scottsco';
raw_key RAW(128) :=
UTL_RAW.CAST_TO_RAW(CONVERT(key_string,'AL32UTF8','US7ASCII'));
encrypted_raw RAW(2048);
encrypted_string VARCHAR2(2048);
decrypted_raw RAW(2048);
decrypted_string VARCHAR2(2048);
-- Begin testing Encryption:
BEGIN
dbms_output.put_line('> Input String : ' ||
CONVERT(UTL_RAW.CAST_TO_VARCHAR2(raw_input),'US7ASCII','AL32UTF8'));
dbms_output.put_line('> ========= BEGIN TEST Encrypt =========');
encrypted_raw := dbms_crypto.Encrypt(
src => raw_input,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
dbms_output.put_line('> Encrypted hex value : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
decrypted_raw := dbms_crypto.Decrypt(
src => encrypted_raw,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
decrypted_string :=
CONVERT(UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw),'US7ASCII','AL32UTF8');
dbms_output.put_line('> Decrypted string output : ' ||
decrypted_string);
if input_string = decrypted_string THEN
dbms_output.put_line('> String DES Encyption and Decryption successful');
END if;
dbms_output.put_line('');
dbms_output.put_line('> ========= BEGIN TEST Hash =========');
encrypted_raw := dbms_crypto.Hash(
src => raw_input,
typ => DBMS_CRYPTO.HASH_SH1);
dbms_output.put_line('> Hash value of input string : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('> ========= BEGIN TEST Mac =========');
encrypted_raw := dbms_crypto.Mac(
src => raw_input,
typ => DBMS_CRYPTO.HMAC_MD5,
key => raw_key);
dbms_output.put_line('> Message Authentication Code : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('');
dbms_output.put_line('> End of DBMS_CRYPTO tests ');
END;
/
DECLARE
input_string VARCHAR2(16) := 'tigertigertigert';
raw_input RAW(128) :=
UTL_RAW.CAST_TO_RAW(CONVERT(input_string,'AL32UTF8','US7ASCII'));
key_string VARCHAR2(8) := 'scottsco';
raw_key RAW(128) :=
UTL_RAW.CAST_TO_RAW(CONVERT(key_string,'AL32UTF8','US7ASCII'));
encrypted_raw RAW(2048);
encrypted_string VARCHAR2(2048);
decrypted_raw RAW(2048);
decrypted_string VARCHAR2(2048);
-- Begin testing Encryption:
BEGIN
dbms_output.put_line('> Input String : ' ||
CONVERT(UTL_RAW.CAST_TO_VARCHAR2(raw_input),'US7ASCII','AL32UTF8'));
dbms_output.put_line('> ========= BEGIN TEST Encrypt =========');
encrypted_raw := dbms_crypto.Encrypt(
src => raw_input,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
dbms_output.put_line('> Encrypted hex value : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
decrypted_raw := dbms_crypto.Decrypt(
src => encrypted_raw,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
decrypted_string :=
CONVERT(UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw),'US7ASCII','AL32UTF8');
dbms_output.put_line('> Decrypted string output : ' ||
decrypted_string);
if input_string = decrypted_string THEN
dbms_output.put_line('> String DES Encyption and Decryption successful');
END if;
dbms_output.put_line('');
dbms_output.put_line('> ========= BEGIN TEST Hash =========');
encrypted_raw := dbms_crypto.Hash(
src => raw_input,
typ => DBMS_CRYPTO.HASH_SH1);
dbms_output.put_line('> Hash value of input string : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('> ========= BEGIN TEST Mac =========');
encrypted_raw := dbms_crypto.Mac(
src => raw_input,
typ => DBMS_CRYPTO.HMAC_MD5,
key => raw_key);
dbms_output.put_line('> Message Authentication Code : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('');
dbms_output.put_line('> End of DBMS_CRYPTO tests ');
END;
/
88/91
附录4:DBMS_CRYPTO包样例
♠ 用dbms_crypto-11g:
♠ AES 256-Bit 数据加密与解密: declare
input_string VARCHAR2 (200) := 'Secret Message';
output_string VARCHAR2 (200);
encrypted_raw RAW (2000); -- stores encrypted binary text
decrypted_raw RAW (2000); -- stores decrypted binary text
num_key_bytes NUMBER := 256/8; -- key length 256 bits (32 bytes)
key_bytes_raw RAW (32); -- stores 256-bit encryption key
encryption_type PLS_INTEGER := -- total encryption type
DBMS_CRYPTO.ENCRYPT_AES256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
begin
DBMS_OUTPUT.PUT_LINE ('Original string: ' || input_string);
key_bytes_raw := DBMS_CRYPTO.RANDOMBYTES (num_key_bytes);
encrypted_raw := DBMS_CRYPTO.ENCRYPT
(
src => UTL_I18N.STRING_TO_RAW (input_string, 'AL32UTF8'),
typ => encryption_type,
key => key_bytes_raw
);
-- The encrypted value in the encrypted_raw variable can be used here:
decrypted_raw := DBMS_CRYPTO.DECRYPT
(
src => encrypted_raw,
typ => encryption_type,
key => key_bytes_raw
);
output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string);
end;
declare
input_string VARCHAR2 (200) := 'Secret Message';
output_string VARCHAR2 (200);
encrypted_raw RAW (2000); -- stores encrypted binary text
decrypted_raw RAW (2000); -- stores decrypted binary text
num_key_bytes NUMBER := 256/8; -- key length 256 bits (32 bytes)
key_bytes_raw RAW (32); -- stores 256-bit encryption key
encryption_type PLS_INTEGER := -- total encryption type
DBMS_CRYPTO.ENCRYPT_AES256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
begin
DBMS_OUTPUT.PUT_LINE ('Original string: ' || input_string);
key_bytes_raw := DBMS_CRYPTO.RANDOMBYTES (num_key_bytes);
encrypted_raw := DBMS_CRYPTO.ENCRYPT
(
src => UTL_I18N.STRING_TO_RAW (input_string, 'AL32UTF8'),
typ => encryption_type,
key => key_bytes_raw
);
-- The encrypted value in the encrypted_raw variable can be used here:
decrypted_raw := DBMS_CRYPTO.DECRYPT
(
src => encrypted_raw,
typ => encryption_type,
key => key_bytes_raw
);
output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string);
end;
89/91
附录5:DBMS_CRYPTO包样例
♠ 用dbms_crypto-11g:
♠ BLOB 数据加密与解密: *Creates a table for the BLOB column
*Inserts the raw values into that table
*Encrypts the raw data
*Decrypts the encrypted data
The blob_test.sql procedure follows:
-- 1. Create a table for BLOB column:
create table table_lob (id number, loc blob);
-- 2. Insert 3 empty lobs for src/enc/dec:
insert into table_lob values (1, EMPTY_BLOB());
insert into table_lob values (2, EMPTY_BLOB());
insert into table_lob values (3, EMPTY_BLOB());
set echo on
set serveroutput on
declare
srcdata RAW(1000);
srcblob BLOB;
encrypblob BLOB;
encrypraw RAW(1000);
encrawlen BINARY_INTEGER;
decrypblob BLOB;
decrypraw RAW(1000);
decrawlen BINARY_INTEGER;
leng INTEGER;
begin
-- RAW input data 16 bytes
srcdata := hextoraw('6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D');
dbms_output.put_line('---');
dbms_output.put_line('input is ' || srcdata);
dbms_output.put_line('---');
-- select empty lob locators for src/enc/dec
select loc into srcblob from table_lob where id = 1;
select loc into encrypblob from table_lob where id = 2;
select loc into decrypblob from table_lob where id = 3;
dbms_output.put_line('Created Empty LOBS');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(srcblob);
IF leng IS NULL THEN
dbms_output.put_line('Source BLOB Len NULL ');
ELSE
dbms_output.put_line('Source BLOB Len ' || leng);
END IF;
leng := DBMS_LOB.GETLENGTH(encrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Encrypt BLOB Len NULL ');
ELSE
dbms_output.put_line('Encrypt BLOB Len ' || leng);
END IF;
leng := DBMS_LOB.GETLENGTH(decrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Decrypt BLOB Len NULL ');
ELSE
dbms_output.put_line('Decrypt BLOB Len ' || leng);
END IF;
-- 3. Write source raw data into blob:
DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.WRITEAPPEND (srcblob, 16, srcdata);
DBMS_LOB.CLOSE (srcblob);
dbms_output.put_line('Source raw data written to source blob');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(srcblob);
IF leng IS NULL THEN
dbms_output.put_line('source BLOB Len NULL ');
ELSE
dbms_output.put_line('Source BLOB Len ' || leng);
END IF;
/*
* Procedure Encrypt
* Arguments: srcblob -> Source BLOB
* encrypblob -> Output BLOB for encrypted data
* DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES
* Chaining : CBC
* Padding : PKCS5
* 256 bit key for AES passed as RAW
* ->
hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
* IV (Initialization Vector) for AES algo passed as RAW
* -> hextoraw('00000000000000000000000000000000')
*/
DBMS_CRYPTO.Encrypt(encrypblob,
srcblob,
DBMS_CRYPTO.AES_CBC_PKCS5,
hextoraw ('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'),
hextoraw('00000000000000000000000000000000'));
dbms_output.put_line('Encryption Done');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(encrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Encrypt BLOB Len NULL');
ELSE
dbms_output.put_line('Encrypt BLOB Len ' || leng);
END IF;
-- 4. Read encrypblob to a raw:
encrawlen := 999;
DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.READ (encrypblob, encrawlen, 1, encrypraw);
DBMS_LOB.CLOSE (encrypblob);
dbms_output.put_line('Read encrypt blob to a raw');
dbms_output.put_line('---');
dbms_output.put_line('Encrypted data is (256 bit key) ' || encrypraw);
dbms_output.put_line('---');
/*
* Procedure Decrypt
* Arguments: encrypblob -> Encrypted BLOB to decrypt
* decrypblob -> Output BLOB for decrypted data in RAW
* DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES
* Chaining : CBC
* Padding : PKCS5
* 256 bit key for AES passed as RAW (same as used during Encrypt)
* ->
hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
* IV (Initialization Vector) for AES algo passed as RAW (same as
used during Encrypt)
* -> hextoraw('00000000000000000000000000000000')
*/
DBMS_CRYPTO.Decrypt(decrypblob,
encrypblob,
DBMS_CRYPTO.AES_CBC_PKCS5,
hextoraw
('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'),
hextoraw('00000000000000000000000000000000'));
leng := DBMS_LOB.GETLENGTH(decrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Decrypt BLOB Len NULL');
ELSE
dbms_output.put_line('Decrypt BLOB Len ' || leng);
END IF;
-- Read decrypblob to a raw
decrawlen := 999;
DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.READ (decrypblob, decrawlen, 1, decrypraw);
DBMS_LOB.CLOSE (decrypblob);
dbms_output.put_line('Decrypted data is (256 bit key) ' || decrypraw);
dbms_output.put_line('---');
DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (srcblob, 0);
DBMS_LOB.CLOSE (srcblob);
DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (encrypblob, 0);
DBMS_LOB.CLOSE (encrypblob);
DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (decrypblob, 0);
DBMS_LOB.CLOSE (decrypblob);
end;
/
truncate table table_lob;
drop table table_lob;
*Creates a table for the BLOB column
*Inserts the raw values into that table
*Encrypts the raw data
*Decrypts the encrypted data
The blob_test.sql procedure follows:
-- 1. Create a table for BLOB column:
create table table_lob (id number, loc blob);
-- 2. Insert 3 empty lobs for src/enc/dec:
insert into table_lob values (1, EMPTY_BLOB());
insert into table_lob values (2, EMPTY_BLOB());
insert into table_lob values (3, EMPTY_BLOB());
set echo on
set serveroutput on
declare
srcdata RAW(1000);
srcblob BLOB;
encrypblob BLOB;
encrypraw RAW(1000);
encrawlen BINARY_INTEGER;
decrypblob BLOB;
decrypraw RAW(1000);
decrawlen BINARY_INTEGER;
leng INTEGER;
begin
-- RAW input data 16 bytes
srcdata := hextoraw('6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D');
dbms_output.put_line('---');
dbms_output.put_line('input is ' || srcdata);
dbms_output.put_line('---');
-- select empty lob locators for src/enc/dec
select loc into srcblob from table_lob where id = 1;
select loc into encrypblob from table_lob where id = 2;
select loc into decrypblob from table_lob where id = 3;
dbms_output.put_line('Created Empty LOBS');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(srcblob);
IF leng IS NULL THEN
dbms_output.put_line('Source BLOB Len NULL ');
ELSE
dbms_output.put_line('Source BLOB Len ' || leng);
END IF;
leng := DBMS_LOB.GETLENGTH(encrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Encrypt BLOB Len NULL ');
ELSE
dbms_output.put_line('Encrypt BLOB Len ' || leng);
END IF;
leng := DBMS_LOB.GETLENGTH(decrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Decrypt BLOB Len NULL ');
ELSE
dbms_output.put_line('Decrypt BLOB Len ' || leng);
END IF;
-- 3. Write source raw data into blob:
DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.WRITEAPPEND (srcblob, 16, srcdata);
DBMS_LOB.CLOSE (srcblob);
dbms_output.put_line('Source raw data written to source blob');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(srcblob);
IF leng IS NULL THEN
dbms_output.put_line('source BLOB Len NULL ');
ELSE
dbms_output.put_line('Source BLOB Len ' || leng);
END IF;
/*
* Procedure Encrypt
* Arguments: srcblob -> Source BLOB
* encrypblob -> Output BLOB for encrypted data
* DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES
* Chaining : CBC
* Padding : PKCS5
* 256 bit key for AES passed as RAW
* ->
hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
* IV (Initialization Vector) for AES algo passed as RAW
* -> hextoraw('00000000000000000000000000000000')
*/
DBMS_CRYPTO.Encrypt(encrypblob,
srcblob,
DBMS_CRYPTO.AES_CBC_PKCS5,
hextoraw ('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'),
hextoraw('00000000000000000000000000000000'));
dbms_output.put_line('Encryption Done');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(encrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Encrypt BLOB Len NULL');
ELSE
dbms_output.put_line('Encrypt BLOB Len ' || leng);
END IF;
-- 4. Read encrypblob to a raw:
encrawlen := 999;
DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.READ (encrypblob, encrawlen, 1, encrypraw);
DBMS_LOB.CLOSE (encrypblob);
dbms_output.put_line('Read encrypt blob to a raw');
dbms_output.put_line('---');
dbms_output.put_line('Encrypted data is (256 bit key) ' || encrypraw);
dbms_output.put_line('---');
/*
* Procedure Decrypt
* Arguments: encrypblob -> Encrypted BLOB to decrypt
* decrypblob -> Output BLOB for decrypted data in RAW
* DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES
* Chaining : CBC
* Padding : PKCS5
* 256 bit key for AES passed as RAW (same as used during Encrypt)
* ->
hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
* IV (Initialization Vector) for AES algo passed as RAW (same as
used during Encrypt)
* -> hextoraw('00000000000000000000000000000000')
*/
DBMS_CRYPTO.Decrypt(decrypblob,
encrypblob,
DBMS_CRYPTO.AES_CBC_PKCS5,
hextoraw
('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'),
hextoraw('00000000000000000000000000000000'));
leng := DBMS_LOB.GETLENGTH(decrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Decrypt BLOB Len NULL');
ELSE
dbms_output.put_line('Decrypt BLOB Len ' || leng);
END IF;
-- Read decrypblob to a raw
decrawlen := 999;
DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.READ (decrypblob, decrawlen, 1, decrypraw);
DBMS_LOB.CLOSE (decrypblob);
dbms_output.put_line('Decrypted data is (256 bit key) ' || decrypraw);
dbms_output.put_line('---');
DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (srcblob, 0);
DBMS_LOB.CLOSE (srcblob);
DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (encrypblob, 0);
DBMS_LOB.CLOSE (encrypblob);
DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (decrypblob, 0);
DBMS_LOB.CLOSE (decrypblob);
end;
/
truncate table table_lob;
drop table table_lob;
90/91
参考资源
♠ Oracle 原厂: ♠ Oracle® Database
♠ Advanced Security Administrator’s Guide
♠ 10g Release 2 (10.2) B14268-01
♠ Oracle® Database
♠ Advanced Security Administrator’s Guide
♠ 11g Release 2 (11.2)E10746-01
91/91
参考资源
♠ Oracle 原厂: ♠ Oracle® Database Security Guide
11g Release 2 (11.2)
Part Number E10574-04