加密技术是最常用的安全保密手段,利用技术手段把重要的数据变为乱码(加密)传送,到达目的地后再用相同或不同的手段还原(解密)。
加密技术包括两个元素: 算法和密钥 。算法是将普通的信息或者可以理解的信息与一串数字(密钥)结合,产生不可理解的密文的步骤,密钥是用来对数据进行编码和解密的一种算法。在安全保密中,可通过适当的钥加密技术和管理机制来保证网络的信息通信安全。
密钥加密技术的密码体制分为 对称密钥体制 和 非对称密钥体制 两种。相应地,对数据加密的技术分为两类,即 对称加密 (私人密钥加密)和 非对称加密 (公开密钥加密)。对称加密以数据加密标准( DES , Data Encryption Standard )算法为典型代表,非对称加密通常以 RSA ( Rivest Shamir Ad1eman )算法为代表。对称加密的加密密钥和解密密钥相同,而非对称加密的加密密钥和解密密钥不同,加密密钥可以公开而解密密钥需要保密。
什么是对称加密技术 ?
对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,这种方法在密码学中叫做 对称加密算法 ,对称加密算法使用起来简单快捷,密钥较短,且破译困难,除了数据加密标准( DES ),另一个对称密钥加密系统是国际数据加密算法( IDEA ),它比 DES 的加密性好,而且对计算机功能要求也没有那么高。 IDEA 加密标准由 PGP ( Pretty Good Privacy )系统使用。
什么是非对称加密技术 ?
1976 年,美国学者 Dime 和 Henman 为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。与对称加密算法不同,非对称加密算法需要两个密钥: 公开密钥 ( publickey )和 私有密钥 ( privatekey )。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
RAW ,类似于 CHAR ,声明方式 RAW(L) , L 为长度,以字节为单位,作为数据库列最大 2000 ,作为变量最大 32767 字节。
Oracle 中用于保存 位串 的数据类型是 RAW , LONG RAW 。
RAW 类型的好处:在网络中的计算机之间传输 RAW 数据时,或者使用 oracle 实用程序将 RAW 数据从一个数据库移到另一个数据库时, Oracle 服务器不执行字符集转换。存储实际列值所需要的字节数大小随每行大小而异,最多为 2,000 字节。可能这样的数据类型在数据库效率上会提高,而且对数据由于字符集不同而导致不一致的可能性也排除了。
对 Oracle 内部数据的加密,可以简单得使用 DBMS_CRYPTO 来进行,效果还是不错的,而且使用也比较方便,所以今天专门来学习一下这个包的使用方法。在使用之前,要注意两件事情:
1) DBMS_CRYPTO 包是 10g 才有的,如果在 10g 以前的版本,使用 DBMS_OBFUSCATION_TOOLKIT 包;
2) DBMS_CRYPTO 默认只有 SYSDBA 用户才可执行,所以其他的任何用户都需要 SYSDBA 进行赋权。
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
创建一张表,用来存放 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>
函数如下:
解释:
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
函数如下:
对应的解密函数:
DBMS_CRYPTO.DECRYPT
创建测试表 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>
说明: 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 条评论