oracle 数据库加密技术
(2016-12-23 10:37:09)
标签:
oraclewallettdedbms_crypto |
oracle 数据库加密技术
11g以后数据库扩展了之前原有的两项加密技术,TDE和dbms_crypto包来进行数据加密;TDE自动化管理,可用于DG,但OGG之间在11g会出现数据同步异常(自己测试没有通过),SR解答说升级到12C可以解决;dbms_crypto包主要用于手动处理,管理难度稍大,在加上wrap即可实现代码的加密(不过听说wrap可以实现反向解密了,并且直接拷贝wrap加密后的代码也能执行),本文由不正之处,还请指正,上例:
TDE:
1、创建和管理Oracle钱夹
1)创建一个新目录,并指定为wallet目录,查询
v$encryption_wallet即可找到默认指定路径(当然可以手动指定,不过要在sqlnet.ora中绑定即可)。
$ mkdir -p /u01/app/oracle/admin/orcl/wallet
设置wallet目录的方法很简单,编辑参数文件sqlnet.ora:
$ vi $ORACLE_HOME/network/admin/sqlnet.ora
加入以下信息,保存。
ENCRYPTION_WALLET_LOCATION=
(SOURCE=
(METHOD=file)
(METHOD_DATA=
(DIRECTORY=/u01/app/oracle/admin/orcl/wallet)
)
)
2.创建master key文件,指定wallet密码
使用SYS用户登陆,通过以下命令建立加密文件:
SQL> alter system set encryption key identified by "wjw";
其中,wjw为wallet密码。Oracle Wallet是一个可以打开关闭的功能组件,设置密码之后,只有通过密码口令可以启用wallet功能。
此时,在设置的目录下会多出一个ewallet.p12文件。这就是生成的master key文件。
3.启动和关闭Wallet
启动Wallet:
SQL> alter system set encryption wallet open identified by "wjw";
关闭Wallet:
SQL> alter system set encryption wallet close identified by "wjw";
可以通过以下语句查询Wallet是否在打开状态:
SQL> select * from v$encryption_wallet;
4.加密数据列
在创建了主密匙后,可以在希望加密的列的名字后使用ENCRYPT关键字,来加密表列。
在创建表时加密列:
SQL> create table t
(id number primary key,
name varchar2(30) encrypt);
加密已有表中的某个列:
SQL> alter table employees modify (emp_id encrypt);
为表新增一个加密列:
SQL> alter table employees add (encrypt_id number(9) encrypt);
可以使用下列命令查看表中的加密列:
SQL> desc 表名称;
如果处于某种原因想关闭加密,则可以使用DECRYPT关键字:
SQL> alter table employees modify(emp_id decrypt);
5.加密表空间
1) 表空间加密的限制:
l
不能加密临时和撤销表空间
l
不能更改加密表空间的安全密匙
l
不能加密外部表
2) 加密表空间示例:
SQL> create tablespace wjw
datafile '/u01/app/oracle/oradata/orcl/wjw01.dbf' size 500m
encryption
default storage(encrypt);
其中encryption表时数据库使用默认的加密算法DES128,可以在encryption后面使用using子句来指定另外的算法,如:
SQL> create tablespace wjw
datafile '/u01/app/oracle/oradata/orcl/wjw01.dbf' size 500m
encryption using '3DES168'
default storage(encrypt);
3) 检查一个表空间是否加密:
SQL> select encrypted from dba_tablespaces;
1)
$ mkdir -p /u01/app/oracle/admin/orcl/wallet
设置wallet目录的方法很简单,编辑参数文件sqlnet.ora:
$ vi $ORACLE_HOME/network/admin/sqlnet.ora
加入以下信息,保存。
ENCRYPTION_WALLET_LOCATION=
2.
使用SYS用户登陆,通过以下命令建立加密文件:
SQL> alter system set encryption key identified by "wjw";
其中,wjw为wallet密码。Oracle Wallet是一个可以打开关闭的功能组件,设置密码之后,只有通过密码口令可以启用wallet功能。
此时,在设置的目录下会多出一个ewallet.p12文件。这就是生成的master key文件。
3.
启动Wallet:
SQL> alter system set encryption wallet open identified by "wjw";
关闭Wallet:
SQL> alter system set encryption wallet close identified by "wjw";
可以通过以下语句查询Wallet是否在打开状态:
SQL> select * from v$encryption_wallet;
4.加密数据列
在创建了主密匙后,可以在希望加密的列的名字后使用ENCRYPT关键字,来加密表列。
在创建表时加密列:
SQL> create table t
(id number primary key,
name varchar2(30) encrypt);
加密已有表中的某个列:
SQL> alter table employees modify (emp_id encrypt);
SQL> alter table employees add (encrypt_id number(9) encrypt);
SQL> desc 表名称;
如果处于某种原因想关闭加密,则可以使用DECRYPT关键字:
SQL> alter table employees modify(emp_id decrypt);
5.加密表空间
1)
l
l
l
2)
SQL> create tablespace wjw
SQL> create tablespace wjw
3)
SQL> select encrypted from dba_tablespaces;
7.在加密列时,存在两个选项:Salt和No Salt。
Salt在加密前对数据增加随即字符串,增加破解的难度,使得同样的字符串加密结果不同;而对于NO Salt,则同样字符串可以获得同样的加密输出,其安全性相对略低。
默认使用salt加密,但加密后无法创建索引,no salt可以创建索引
8.打开钱包后DG应用进程会自动断开显示无法打开钱包,此时只需要将主库目录下对应的ewallet.p12拷贝至备库对应目录,并修改sqlnet.ora,重启监听,重新应用备库日志即可。
dbms_crypto:
1.直接做出一个shell脚本,此脚本限制密码32位字符,密码输入为隐视,脚本分为父脚本和子脚本,子脚本有两个,可任选其一:
##父脚本
#!/bin/bash
echo "Enter the master key:"
read -s pass1
echo " "
export pass1
##导出变量到子脚本使用
if [ "${#pass1}" -eq 32 ];then
sh /home/oracle/wrap.sh
else
echo "The master key is too short!"
fi
#!/bin/bash
echo "Enter the master key:"
read -s pass1
echo " "
export pass1
if [ "${#pass1}" -eq 32
sh /home/oracle/wrap.sh
else
echo "The master key is too short!"
fi
##子脚本1
#!/bin/bash
#echo "Enter you password:"
###引用父脚本传递的参数
#read -s pass1
#echo " "
echo "please enter again:"
read -s pass2
echo " "
if [ "$pass1" == "$pass2" ];then
echo "create or replace function t_to_test1(string_in in varchar2) return raw is
string_in_raw RAW(128) :=
UTL_RAW.CAST_TO_RAW(string_in);
key_string
varchar2(32) := '$pass2';
key_raw
RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
encrypted_raw RAW(128);
begin
encrypted_raw :=
dbms_crypto.Encrypt(src => string_in_raw,
typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
key => key_raw);
return encrypted_raw;
end;" >/home/oracle/wrap.sql
wrap iname=/home/oracle/wrap.sql
sqlplus test/test <<EOF
@wrap.plb
commit;
EOF
#!/bin/bash
#echo "Enter you password:"
#read -s pass1
#echo " "
echo "please enter again:"
read -s pass2
echo " "
if [ "$pass1" == "$pass2" ];then
echo "create or replace function t_to_test1(string_in in varchar2) return raw is
wrap iname=/home/oracle/wrap.sql
sqlplus test/test <<EOF
@wrap.plb
commit;
EOF
rm -f wrap.plb
rm -f wrap.sql
echo "create or replace function t_to_test2(raw_in in raw) return varchar2 is
string_out
varchar2(50);
key_string
varchar2(32) := '$pass2';
key_raw
RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
decrypted_raw RAW(128);
begin
decrypted_raw :=
dbms_crypto.Decrypt(src => raw_in,
typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
key => key_raw);
string_out :=
UTL_RAW.cast_to_varchar2(decrypted_raw);
return string_out;
end;" > /home/oracle/wrap.sql
rm -f wrap.sql
echo "create or replace function t_to_test2(raw_in in raw) return varchar2 is
wrap iname=/home/oracle/wrap.sql
sqlplus test/test <<EOF
@wrap.plb
commit;
EOF
sqlplus test/test <<EOF
@wrap.plb
commit;
EOF
rm -f wrap.plb
rm -f wrap.sql
rm -f wrap.sql
echo "OK!"
else
echo "Not match!"
fi
else
echo "Not match!"
fi
##子脚本2
#!/bin/bash
echo "please enter again:"
read -s pass2
echo " "
if [ "$pass1" == "$pass2" ];then
echo "create or replace function t_to_test1(string_in in varchar2) return raw is
string_in_raw RAW(128) :=
UTL_RAW.CAST_TO_RAW(string_in);
key_string
varchar2(32) := '$pass2';
key_raw
RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
encrypted_raw RAW(128);
d_dbid1
number(20);
d_dbid2
number(20) := 1223794491;;--此处为数据库dbid,为防止其他人到其他库直接复制运行
echo "please enter again:"
read -s pass2
echo " "
if [ "$pass1" == "$pass2" ];then
echo "create or replace function t_to_test1(string_in in varchar2) return raw is
begin
select dbid into d_dbid1 from v\$database;
if d_dbid1 = d_dbid2 then
encrypted_raw := dbms_crypto.Encrypt(src => string_in_raw,
typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
key => key_raw);
return
encrypted_raw;
end if;
end;" >/home/oracle/wrap.sql
wrap iname=/home/oracle/wrap.sql
sqlplus test/test <<EOF
@wrap.plb
commit;
EOF
wrap iname=/home/oracle/wrap.sql
sqlplus test/test <<EOF
@wrap.plb
commit;
EOF
rm -f wrap.sql
rm -f wrap.plb
echo "create or replace function t_to_test2(raw_in in raw)
return varchar2 is
string_out
varchar2(50);
key_string
varchar2(32) := '$pass2';
key_raw
RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
decrypted_raw RAW(128);
d_dbid1
number(20);
d_dbid2
number(20) := 1223794491;--此处为数据库dbid,为防止其他人到其他库直接复制运行
begin
select dbid into d_dbid1 from v\$database;
if d_dbid1 = d_dbid2 then
decrypted_raw := dbms_crypto.Decrypt(src => raw_in,
typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
key => key_raw);
string_out :=
UTL_RAW.cast_to_varchar2(decrypted_raw);
return
string_out;
end if;
end;" > /home/oracle/wrap.sql
wrap iname=/home/oracle/wrap.sql
sqlplus test/test <<EOF
begin
end;" > /home/oracle/wrap.sql
wrap iname=/home/oracle/wrap.sql
sqlplus test/test <<EOF
@wrap.plb
commit;
EOF
rm -f wrap.plb
rm -f wrap.sql
echo "OK!"
else
echo "Not match!"
fi
commit;
EOF
rm -f wrap.plb
rm -f wrap.sql
echo "OK!"
else
echo "Not match!"
fi