DBMS_CRYPTO encryption 加密 AES

转自[url]http://yangbo-ora.blogspot.com/2008/01/dbmscrypto-encryption-aes.html[/url]
那个页面被墙 只好在这复制下了


目前主流的加密方法大致有MD5、SHA-1、DES、Triple DES、AES,目前MD5、SHA-1、DES都已经有破解方法,Triple DES、AES还没有被破解的记载,其中AES是最新最安全的加密方法,最多可提供256位的加密。

Oracle 9i提供MD5、DES、Triple DES,而Oracle 10g和10g R2提供了上面提到的所有加密方法供选择。


鉴于以上情况,针对Oracle 10g,我的想法是使用DBMS_CRYPTO包提供的Triple DES或者AES进行加密(Oracle 9i中没有这个包)。

与其他方法相比,这样做的优点是:


1. Triple DES、AES是最安全的加密方法,没有被破解的记载

2. 有可逆和不可逆两种加密选择

3. 支持对BLOB和CLOB加密


1.脚本

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

加密函数

create or replace function encrypt256(v_input varchar2) return raw

is

v_result raw(256);

c_key char(32) := '1q2wa3es4rz5tx6ycD*UF8tif9ogjen2';

begin

v_result := DBMS_CRYPTO.ENCRYPT(

UTL_I18N.STRING_TO_RAW(v_input, 'AL32UTF8'),

DBMS_CRYPTO.ENCRYPT_AES256+DBMS_CRYPTO.CHAIN_CBC+DBMS_CRYPTO.PAD_PKCS5,

UTL_I18N.STRING_TO_RAW(c_key, 'AL32UTF8'));

return v_result;

end;

/



解密函数

create or replace function decrypt256(v_input raw) return varchar2

is

v_result raw(256);

c_key char(32) := '1q2wa3es4rz5tx6ycD*UF8tif9ogjen2';

begin

v_result := DBMS_CRYPTO.DECRYPT(

v_input,

DBMS_CRYPTO.ENCRYPT_AES256+DBMS_CRYPTO.CHAIN_CBC+DBMS_CRYPTO.PAD_PKCS5,

UTL_I18N.STRING_TO_RAW(c_key, 'AL32UTF8'));

return UTL_I18N.RAW_TO_CHAR(v_result, 'AL32UTF8');

end;

/


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


2.功能演示


SQL> insert into test values(1,encrypt256('一次成功')); <--用户插入或者修改数据时这样使用


已创建 1 行。


SQL> commit;


提交完成。


SQL> select * from test;


ID RAWS

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

1 597B660AFD6CC3A90D064B00DF7EB80D <--数据已经被密文保存


SQL> select id,raws from test where raws=encrypt256('一次成功'); <--核对或者查找时这样使用


ID RAWS

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

1 597B660AFD6CC3A90D064B00DF7EB80D


SQL> select id,decrypt256(raws) raws from test; <--解密方法和结果


ID RAWS

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

1 一次成功


3. 加密对性能的影响

在我的测试中,逻辑读的量基本不变,扫描索引的耗时变为不加密时的10.8倍(66us --> 717us)。

INDEX RANGE SCAN YB_IND_TESTT_1 (cr=3 pr=0 pw=0 time=66 us)(object id 81639)

INDEX RANGE SCAN YB_IND_TESTT_2 (cr=3 pr=0 pw=0 time=717 us)(object id 81640)

这种耗时的增加与使用何种加密方式无关。


4. 对于脚本中密钥的保护

虽然密钥仍然是写死在脚本中,但是不用担心开发人员或者数据库管理人员会得到密钥,这里使用的方法是Oracle提供的wrap程序包,使用这个包可以将脚本以不可逆的方式加密。


例如:创建encrypt256()这个函数的脚本经过加密以后,会变成下面这样。

这样的脚本仍然可以创建函数,但没有人知道这个函数内容更没有人知道密钥是什么。

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

create or replace function encrypt256 wrapped

a000000

354

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

8

18b 15c

cSBfE65CYUS4abCCuiwqeQWAEZEwg/DIDK5qfC9Grfjqzqc2UfIyWpTjI7h2sFSyE4XQwwA7

LyfVV6mp8no/ANyNnp4A9SCHcrSaWUNnVD2mjcrSwg1WkEakxRGQY6SxBkD2b8xiO+tnKg8v

AVoHo6vqBfl2I4SJtjfHvhrte1k0+SPy1giZEp0MKyCcZA8pMwubQg9BmMUFIthkQXjQCklv

XRrIgkQkckLqk2iraDchjDcWFNJyV7qMqxd8ZSvVdWt5S0mISwurpXs4/yuTL5W1R4A/Z9Hw

0FII+JeAzKlRL1sFp5y0/wKhhl5rn5V2yjphQHv+r8dma0dyvPumJQEJ


/

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


5. 几点提示和注意事项

(1) 示例脚本中被加密的字段最大255字节因此需要开发人员在程序中判断长度;

这个长度限制根据需要可以调整到最大1999字节。

(2) BLOB和CLOB类型的数据也可以加密

(3) 由于使用了wrap方式保护密钥且这个方法不可逆,所以密钥必须妥善保存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
grant execute on dbms_crypto to system; declare input_string VARCHAR2 (200) := 'Secret Message'; output_string VARCHAR2(2000); encrypted_raw RAW(2000); decrypted_raw RAW(2000); num_key_bytes NUMBER := 256/8; key_bytes_raw RAW(32); encryption_type PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5; begin DBMS_OUTPUT.PUT_LINE(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 ); 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(output_string); end; declare l_src_data varchar2(20); l_type pls_integer :=DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5; l_key varchar2(20) :='0123456789123456'; l_encval raw(2000); CURSOR secret_cursor IS select phonenumber from customer; begin OPEN secret_cursor; LOOP FETCH secret_cursor INTO l_src_data; l_encval :=dbms_crypto.encrypt( src=>utl_i18n.string_to_raw(l_src_data,'AL32UTF8'), typ=>l_type, key=>utl_i18n.string_to_raw(l_key,'AL32UTF8')); DBMS_OUTPUT.PUT_LINE (l_encval); EXIT WHEN secret_cursor%NOTFOUND; END LOOP; CLOSE secret_cursor; end; declare ;_src_data row(100) :=hextoraw("190248129038903853275ijdkvjkad'); l_type pls_integer :=dbms_crypto.encrypt_aes128+ + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5; l_key varchar2(20) :='0123456789123456'; l_decval raw(200); begin l_decval :=dbms_crypto.decrypt( src=>l_src_data, typ=>l_type, key=>utl_i18n.string_to_raw(l_key,'AL32UTF8')); end; SELECT Price FROM PRODUCT WHERE ProductID = 5;修正这一段代码
05-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值