zftang
作者zftang·2020-04-15 11:06
其它·小白一枚

Oracle之DBMS_CRYPTO加密解密方法

字数 6320阅读 3199评论 0赞 0

1. 概念

1.1. 加密解密技术

加密技术是最常用的安全保密手段,利用技术手段把重要的数据变为乱码(加密)传送,到达目的地后再用相同或不同的手段还原(解密)。

加密技术包括两个元素: 算法和密钥 。算法是将普通的信息或者可以理解的信息与一串数字(密钥)结合,产生不可理解的密文的步骤,密钥是用来对数据进行编码和解密的一种算法。在安全保密中,可通过适当的钥加密技术和管理机制来保证网络的信息通信安全。

密钥加密技术的密码体制分为 对称密钥体制 和 非对称密钥体制 两种。相应地,对数据加密的技术分为两类,即 对称加密 (私人密钥加密)和 非对称加密 (公开密钥加密)。对称加密以数据加密标准( DES , Data Encryption Standard )算法为典型代表,非对称加密通常以 RSA ( Rivest Shamir Ad1eman )算法为代表。对称加密的加密密钥和解密密钥相同,而非对称加密的加密密钥和解密密钥不同,加密密钥可以公开而解密密钥需要保密。

什么是对称加密技术 ?

对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,这种方法在密码学中叫做 对称加密算法 ,对称加密算法使用起来简单快捷,密钥较短,且破译困难,除了数据加密标准( DES ),另一个对称密钥加密系统是国际数据加密算法( IDEA ),它比 DES 的加密性好,而且对计算机功能要求也没有那么高。 IDEA 加密标准由 PGP ( Pretty Good Privacy )系统使用。

什么是非对称加密技术 ?

1976 年,美国学者 Dime 和 Henman 为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。与对称加密算法不同,非对称加密算法需要两个密钥: 公开密钥 ( publickey )和 私有密钥 ( privatekey )。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

1.2. RAW 类型

RAW ,类似于 CHAR ,声明方式 RAW(L) , L 为长度,以字节为单位,作为数据库列最大 2000 ,作为变量最大 32767 字节。

Oracle 中用于保存 位串 的数据类型是 RAW , LONG RAW 。

RAW 类型的好处:在网络中的计算机之间传输 RAW 数据时,或者使用 oracle 实用程序将 RAW 数据从一个数据库移到另一个数据库时, Oracle 服务器不执行字符集转换。存储实际列值所需要的字节数大小随每行大小而异,最多为 2,000 字节。可能这样的数据类型在数据库效率上会提高,而且对数据由于字符集不同而导致不一致的可能性也排除了。

2. 使用 DBMS_CRYPTO 包对列加密

对 Oracle 内部数据的加密,可以简单得使用 DBMS_CRYPTO 来进行,效果还是不错的,而且使用也比较方便,所以今天专门来学习一下这个包的使用方法。在使用之前,要注意两件事情:

1) DBMS_CRYPTO 包是 10g 才有的,如果在 10g 以前的版本,使用 DBMS_OBFUSCATION_TOOLKIT 包;

2) DBMS_CRYPTO 默认只有 SYSDBA 用户才可执行,所以其他的任何用户都需要 SYSDBA 进行赋权。

2.1. 赋权限

SQL> select * from v$version;

BANNER


Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

PL/SQL Release 11.2.0.4.0 - Production

CORE 11.2.0.4.0 Production

TNS for 64-bit Windows: Version 11.2.0.4.0 - Production

NLSRTL Version 11.2.0.4.0 - Production

SQL> create user u_des_test identified by iflytek;

User created

SQL> grant execute on DBMS_CRYPTO to u_des_test;

Grant succeeded

2.2. 随机值生成

创建一张表,用来存放 key 值,该值用于加解密。这里创建表是为了存放 key ( key 不能丢失),非必须。

创建表语法如下:

使用 DBMS_CRYPTO 包可以有 3 个函数来生成简单的随机值,包括 3 种——数字、整数、字符。使用这些随机数生成函数是为了在加密时生成随机的密匙。这几个函数的使用很简单,看一下具体例子就可以马上明白:

SQL> select DBMS_CRYPTO.RandomInteger from dual; -- 生成整数 ( 有正有负 )

RANDOMINTEGER


-1713829720

SQL> select DBMS_CRYPTO.RandomNumber from dual; -- 生成 Number( 正数 )

RANDOMNUMBER


1.4101848189

SQL> select DBMS_CRYPTO.RandomBytes(32) from dual; -- 生成 32 位 Bytes( 注意返回的不是 byte 是 raw)

DBMS_CRYPTO.RANDOMBYTES(32)


45DA4AD5B71078CB63298448A4C0D4B3A677B0FF300FB7CF03AF22F72E05A108

SQL>

向表 t_key_info 插入两条测试数据:

SQL> conn u_des_test/iflytek@listener_orcl

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as u_des_test

SQL> INSERT INTO t_key_info VALUES(1, DBMS_CRYPTO.RandomBytes(32), ' 测试一:生成 32 位 Bytes( 注意返回的不是 byte 是 raw)');

1 row inserted

SQL> INSERT INTO t_key_info VALUES(2, DBMS_CRYPTO.RandomBytes(32), ' 测试二:生成 32 位 Bytes( 注意返回的不是 byte 是 raw)');

1 row inserted

SQL> commit;

Commit complete

SQL>

2.3. 加密 / 解密函数

2.3.1. 加密函数: F_ENCRYPT

函数如下:

解释:

DBMS_CRYPTO.ENCRYPT (src IN RAW,

typ IN PLS_INTEGER,

key IN RAW,

iv IN RAW DEFAULT NULL)

RETURN RAW;

1 、 src :需要加密的内容,但是需要转换为 RAW 格式,不能直接对 VARCHAR2 格式加密

2 、 typ :加密类型,由 DBMS_CRYPTO 定义,可以查询 DBMS_CRYPTO 包中的 Declare 部分

3 、 key :即加密的密匙,如需解密则需要知道原先的密匙

4 、 iv : block 密码的选项,一般都置为默认,默认为 null

2.3.2. 解密函数: F_DECRYPT

函数如下:

对应的解密函数:

DBMS_CRYPTO.DECRYPT

2.4. 示例

创建测试表 T_COL_DES_TEST

创建语句如下:

向测试表 T_COL_DES_TEST 插入两种不同密钥( id=1 与 id=2 的 key )加密的数据:

INSERT INTO T_COL_DES_TEST VALUES ( 1 , ' 讯飞测试一 ' , F_ENCRYPT( ' 讯飞测试一 ' ,( SELECT KEY FROM t_key_info WHERE ID = 1 )));

INSERT INTO T_COL_DES_TEST VALUES ( 1 , 'lbjiang@iflytek.com' , F_ENCRYPT( 'lbjiang@iflytek.com' ,( SELECT KEY FROM t_key_info WHERE ID = 1 )));

INSERT INTO T_COL_DES_TEST VALUES ( 2 , ' 讯飞测试二 ' , F_ENCRYPT( ' 讯飞测试二 ' ,( SELECT KEY FROM t_key_info WHERE ID = 2 )));

INSERT INTO T_COL_DES_TEST VALUES ( 2 , 'lbjiang@iflytek.com' , F_ENCRYPT( 'lbjiang@iflytek.com' ,( SELECT KEY FROM t_key_info WHERE ID = 2 )));

查看信息:

SQL> col name format a19

SQL> col des_name format a64

SQL> select * from t_col_des_test; -- desc_name 为加密后的数据

ID NAME DES_NAME


1 讯飞测试一 A96FCFB5ED7091BCC2696C541647C81A

1 lbjiang@iflytek.com EBA78FEB50BDF7E7AC229DD68B357B4C322269F6AB7055F0BA7E9FE0365D6208

2 讯飞测试二 A7E175E7DABA09F4FEDE8D097272E761

2 lbjiang@iflytek.com 6EE51EA691E4E7DF39D53F14A91743FA1A6E156E27F5756600A46BAE7B790696

SQL> SELECT ID,NAME,f_decrypt(des_name,(SELECT KEY FROM t_key_info WHERE ID = 1)) des_name FROM t_col_des_test WHERE ID = 1; -- desc_name 为 id=1 的 key 解密后的数据

ID NAME DES_NAME


1 讯飞测试一 讯飞测试一

1 lbjiang@iflytek.com lbjiang@iflytek.com

SQL> SELECT ID,NAME,f_decrypt(des_name,(SELECT KEY FROM t_key_info WHERE ID = 2)) desc_name FROM t_col_des_test WHERE ID = 2; -- desc_name 为 id=2 的 key 解密后的数据

ID NAME DESC_NAME


2 讯飞测试二 讯飞测试二

2 lbjiang@iflytek.com lbjiang@iflytek.com

SQL>

如果用 id=1 的密钥去解用 id=2 加密的数据:

SQL> SELECT ID,NAME,f_decrypt(des_name,(SELECT KEY FROM t_key_info WHERE ID = 1)) desc_name FROM t_col_des_test WHERE ID = 2;

SELECT ID,NAME,f_decrypt(des_name,(SELECT KEY FROM t_key_info WHERE ID = 1)) desc_name FROM t_col_des_test WHERE ID = 2

ORA-28817: PL/SQL 函数返回错误。

ORA-06512: 在 "SYS.DBMS_CRYPTO_FFI", line 67

ORA-06512: 在 "SYS.DBMS_CRYPTO", line 44

ORA-06512: 在 "U_DES_TEST.F_DECRYPT", line 10

SQL>

3. 说明及规则

说明: INPUT_STRING 为要进行加密的数据。第 5 行,指定加密的算法( encrypt_aes256 ),填充方法( pad_pkcs5 )以及连接方法( chain_cbc )。当对一段数据进行加密时,算法不会对数据整体加密,通常会分成 8 个字节的小块,对每个小块进行加密;如果数据恰好不够 8 位时,这时,需要进行填充,补齐 8 字节。当数据被拆分成小块加密后,需要将其相邻的小块进行连接起来。第 9 行中,使用 encrypt 函数进行加密操作,加密后的结果以 raw 型进行返回。我这里使用的是 utl_i18n.string_to_raw 进行数据类型的转换,这是因为 encrypt 函数不但需要 raw 型数据,而且还需要使用专门的字符集—— AL32UTF8 ,这里如果使用 utl_raw.cast_to_raw ,则会出现“ ORA-06502 ”错误。表 t_key_info 字段 key 的密钥长度要注意一下,这里使用的是 32 位 ,是因为加密算法使用的是 256 位的加密算法,每 8 位进行加密的话,那么 256 除以 8 ,正好是 32 位,所以密钥长度必须是 32 位,不能太长或太短,否则会出现“ ORA-28234 ”错误。

下面我们列出一些 dbms_crypto包加密算法的算法常量

ENCRYPT_DES :标准数据加密。有效的键长度为 56 位,

ENCRYPT_3DES_2KEY :修改过的 3DES ,用两个密钥对每个数据块加密 3 次。有效的键长度为 112 位。

ENCRYPT_3DES :对每一个数据块加密 3 次。有效的键长度为 156 位。

ENCRYPT_AES128 :高级加密标准。有效的键长度为 128 位。

ENCRYPT_AES192 :高级加密标准。有效的键长度为 192 位。

ENCRYPT_AES256 :高级加密标准。有效的键长度为 256 位。

ENCRYPT_RC4 :唯一一个流加密,它被用于加密数据流,而不是离散数据或是表态数据。

DBMS_CRYPTO包的填充常量:

PAD_PKCS5 :用 PKCS#5 填充。

PAD_ZERO :用零填充。

PAD_NONE :不进行填充,如果假设数据块的长度正好是 8 个字节,则可以使用这个方法。

DBMS_CRYPT0包的连接常量

CHAIN_CBC :密码块连接,是最常用的方法。

CHAIN_CFB :加密反馈模式。

CHAIN_ECB :电子源码书格式。

CHAIN_OFB :输入回馈模式。

关于算法的详细信息,请查阅相关资料。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广