存储加密

为了防止用户直接通过数据文件获取用户信息,DM 提供了全面的数据加密的功能,包括:

✔ 透明加密

✔ 半透明加密

✔ 非透明加密

存储加密在保证数据文件安全性的同时,也会带来一定的性能影响,不同的加密算法对性能的影响各有不同,用户需要根据自己的需求来决定是否进行加密以及加密算法的选择。

DM 使用服务器主密钥 SVR_KEY 和数据库主密钥 DB_KEY 进行分级存储加密。SVR_KEY 为服务器主密钥,用于加密数据库主密钥;DB_KEY 用于加密库内密钥,如用户加密密钥、列加密密钥等。

DM 安全版提供了两个系统过程 SP_UPDATE_SVRKEY()和 SP_UPDATE_DBKEY(),分别用于更新密钥 SVR_KEY 和 DB_KEY。

例如,更新服务器主密钥 SVR_KEY。

SQL> SP_UPDATE_SVRKEY();

7.1 透明加密

在透明加密中,密钥生成、密钥管理和加解密过程由数据库管理系统自动完成,用户不可见。透明加密的目的主要是保证存储在数据文件中的敏感数据的安全,并不能保护合法用户的个人私密数据。

7.1.1 全库加密

对 DM 数据库进行全库加密需要在初始化数据库时通过 ENCRYPT_NAME 参数指定全库加密算法,加密密钥由 DM 自动生成。若初始化数据库时不指定 ENCRYPT_NAME 参数,则不进行全库加密。

对全库加密使用的算法存在以下限制:

  1. 加密算法的类型应为 CYT_TYPE_SYM_BLOCK_ENCRYPT 或 CYT_TYPE_SYM_STREAM_ENCRYPT,加密算法类型介绍见 8.1.1 节;

  2. 与数据库初始化参数 PAGE_ENC_SLICE_SIZE 相关

    若 PAGE_ENC_SLICE_SIZE 为 0:

    a) 不支持工作模式为 WORK_MODE_EXTKEY 的加密算法,工作模式介绍见 8.1.1 节,下文中相同;

    b) 不支持块大小(blk_size)为 0, 但扩展长度(EXTEND_SIZE)>4 的加密算法;

    c) 不支持块大小(blk_size)不为 0, 但扩展长度(EXTEND_SIZE)> blk_size 的加密算法;

    d) 不支持块大小(blk_size)>16 的加密算法。

    若 PAGE_ENC_SLICE_SIZE 为非 0:

    a) 不支持扩展长度(EXTEND_SIZE)超过分片大小的加密算法;

    b) 不支持块大小(blk_size)>64 的工作模式为 WORK_MODE_EXTKEY 的加密算法;

    c) 不支持块大小(blk_size)>16 的工作模式非 WORK_MODE_EXTKEY 的加密算法;

    d) 不支持扩展长度(EXTEND_SIZE)为 0, 但工作模式为 WORK_MODE_ECB 或 WORK_MODE_CBC 的加密算法;

    e) 不支持扩展长度为(EXTEND_SIZE)0, 但通过 cipher_get_cipher_text_size()计算得到密文长度与明文不同的加密算法。

指定全库加密时,在 DM 数据库服务器启动及运行的过程中,需要对处理的所有数据页通过指定的加密算法和 DM 自动生成的密钥进行加解密处理。如果数据页读入缓存,需要进行解密后才能使用,在缓存中的数据页进行刷盘时,需要对数据页进行加密后存储到数据文件中。

系统存储函数 SF_GET_ENCRYPT_NAME() 用于获取全库加密算法名。 未使用全库加密时返回 NULL。

例如,使用了全库加密算法 xor1。

SQL> select SF_GET_ENCRYPT_NAME();
行号    SF_GET_ENCRYPT_NAME()
---------- ---------------------
1     xor1

7.1.2 表空间透明加密

DM 支持在创建表空间时指定进行透明加密,语法格式为:

CREATE TABLESPACE [IF NOT EXISTS] <表空间名> <数据文件子句> [<数据页缓冲池子句>] [<存储加密子句>]
<存储加密子句> ::= ENCRYPT WITH <加密算法> [BY <加密密码>]
说明

此处主要说明存储加密相关的语法,其余语法的详细描述请参考《DM8_SQL语言使用手册》,后续小节中相同,不再说明。

使用说明:

  1. < 加密密码 > 必须满足长度大于等于 INI 参数 PWD_MIN_LEN 设置的值,同时不超过 32,且包含大写、小写、数字。若未指定,由 DM 随机生成;
  2. 如果已指定全库加密,则不再支持表空间加密;
  3. < 加密算法 > 的限制与全库加密的基本相同,另外,表空间加密还不支持进行加密扩展的算法,如工作模式为 WORK_MODE_ECB 或 WORK_MODE_CBC 的加密算法、扩展长度 >0 的加密算法、通过 cipher_get_cipher_text_size()计算得到密文长度与明文不同的加密算法,工作模式介绍见 8.1.1 节。

7.1.3 表列透明加密

DM 支持对表的列进行透明加密,支持建表时设置加密列,以及修改表定义时设置加密列。存储加密支持所有的列类型,包括大字段类型。用透明加密的方式加密列上的数据时,在数据库中保存加密该列的密钥,执行 DML 语句的过程中系统能自动获取密钥。

建表或修改表时指定对列进行透明加密的语法格式为:

……
<列定义> ::= <不同类型列定义> [<列定义子句>][<STORAGE子句>] [<透明存储加密子句>]
<透明存储加密子句>::= <透明存储加密子句1>|<透明存储加密子句2>
<透明存储加密子句1>::= ENCRYPT [<透明加密用法>] 
<透明存储加密子句2>::= ENCRYPT <透明加密用法><散列选项>
<透明加密用法> ::= WITH <加密算法> [<透明加密选项>]|
		           <透明加密选项> 
<透明加密选项> ::= <透明加密选项1> |<透明加密选项2> |<透明加密选项3> 
<透明加密选项1> ::= AUTO 
<透明加密选项2> ::= AUTO BY <列存储密钥> 
<透明加密选项3> ::= AUTO BY WRAPPED <列存储密钥的密文>

说明

上述语法格式不完整,主要说明与表列透明加密相关的部分,其他建表相关语法请参考《DM8_SQL语言使用手册》。

使用说明:

  1. 当使用列加密但没有指定加密算法时,缺省使用 AES256_CBC 加密算法;

  2. 指定列加密算法时,算法类型应为 CYT_TYPE_SYM_BLOCK_ENCRYPT 或 CYT_TYPE_SYM_STREAM_ENCRYPT,且算法的工作模式不为 WORK_MODE_EXTKEY、WORK_MODE_ECB_NOPAD 或 WORK_MODE_CBC_NOPAD(加密算法类型、工作模式介绍见 8.1.1 节);虽 DM 支持指定列加密算法为 RC4,但由于该算法安全性较低,并不推荐使用;

  3. 散列算法支持 MD5 和 SHA1 等(可以通过查询动态视图 V​CIPHERS获取更多支持的散列算法:SELECT CYT_NAME FROM VCIPHERS WHERE CYT_TYPE=4;),用于保证用户数据的完整性,若用户数据被非法修改,则能判断该数据不合法;

  4. < 透明加密选项 > 用于指定对当前列进行按列加密。具体规则如下:

    1. < 透明加密选项 > 用于指定对该列进行按列加密。< 透明加密选项 > 缺省和 < 透明加密选项 1> 均使用系统自动生成的秘钥进行列加密。< 透明加密选项 2> 和 < 透明加密选项 3> 使用各自指定的密钥进行列加密。透明加密中按列加密的好处是用户可根据需要灵活设置不同的列秘钥。其中 < 透明加密选项 2> 使用之前需先设置 INI 参数 AUTO_ENCRYPT=1,打开支持列透明加密时用户手动输入 < 列存储密钥 > 开关。
    2. < 列存储密钥 > 必须满足长度大于等于 INI 参数 PWD_MIN_LEN 设置的值,且包含大写、小写、数字。

例 以下是一些对表列进行透明加密的例子。

CREATE TABLE TEST_ENCRYPT1(C1 INT, C2 INT ENCRYPT);
CREATE TABLE TEST_ENCRYPT2(C1 INT, C2 INT ENCRYPT WITH DES_ECB);
CREATE TABLE TEST_ENCRYPT5(C1 INT, C2 INT ENCRYPT WITH DES_ECB HASH WITH MD5 SALT);

7.1.4 其他数据库对象加密

DM 还支持对存储过程、存储函数、触发器、包、类、自定义类型等的定义进行加密,创建时在对象名称后加上“WITH ENCRYPTION ”即可。

例如,创建存储过程 proc_arg,对其定义进行加密。

CREATE OR REPLACE PROCEDURE proc_arg WITH ENCRYPTION(a IN INT, b INT)
AS
BEGIN
    a:=0;
    b:=A+1;
END;

7.1.5 重做日志文件加密

DM 支持对联机日志文件和归档日志文件进行加密,可在创建数据库时通过建库参数 RLOG_ENCRYPT_NAME 指定重做日志文件的加密算法,若未指定则不加密。

RLOG_ENCRYPT_NAME 支持使用第三方加密算法,但不支持工作模式为 WORK_MODE_CBC_NOPAD、WORK_MODE_ECB_NOPAD 或 WORK_MODE_EXTKEY 的加密算法,关于加密算法的工作模式可参考 8.1.1 节。

在 2.2 节中可以看到,创建用户时可以指定存储加密密钥,这个密钥就是为了进行半透明加密时使用的。如果在创建用户时并没有指定存储加密密钥,系统也会自动为用户生成一个默认的加密密钥。

如果在创建表或修改表时指定对表列进行半透明加密,DM 会使用用户的存储加密密钥对数据进行加密。半透明加密列的密文后追加了 4 个字节的 UID,用户查询数据时,若当前会话用户 ID 与列密文数据中存储的 UID 相同,则返回明文,否则返回 NULL。

建表或修改表时指定对列进半透明加密的语法格式为:

……

<列定义> ::= <不同类型列定义> [<列定义子句>]
[<STORAGE子句>] [<半透明存储加密子句>]
<半透明存储加密子句> ::= ENCRYPT [WITH <加密算法>] MANUAL[<散列选项>]
<散列选项> ::= HASH WITH <散列算法> [<加盐选项>]
<加盐选项> ::= [NO] SALT
说明

使用半透明加密时,用户仅能查看到自己插入的数据。

使用说明:

  1. HUGE 表不支持半透明加密列;

  2. 半透明加密列不能作为索引列,索引列也不能修改为半透明加密列;

  3. 半透明加密列不允许添加引用约束;

  4. 若表中包含半透明加密列,则不允许创建聚集索引,同时不允许删除该表原有的聚集索引;

  5. 不允许修改半透明加密列的列定义;

  6. 当增加列、删除列或者修改列定义时,若表中包含半透明加密列,则 INI 参数 ALTER_TABLE_OPT 不能设置为 1,若参数 ALTER_TABLE_OPT 为 1,则系统自动按照参数 ALTER_TABLE_OPT 为 0 时处理,关于参数 ALTER_TABLE_OPT 的详细介绍请参考手册《DM8 系统管理员手册》;

  7. 当增加列且新增列的默认值非 NULL 时,若新增列为半透明加密列,则 INI 参数 ALTER_TABLE_OPT 不能设置为 3,若参数 ALTER_TABLE_OPT 为 3,则系统自动按照参数 ALTER_TABLE_OPT 为 0 时处理;

  8. 若表中包含半透明加密列,则不允许使用 REBUILD COLUMNS 子句修改表,关于 REBUILD COLUMNS 子句的详细介绍请参考手册《DM8_SQL 语言使用手册》;

  9. 物化视图的查询语句中不能涉及半透明加密列;

  10. 若表指定了 USING LONG ROW 存储选项,即支持超长记录存储时,如果表中包含半透明加密列,并且该列的数据类型为字符串类型,则系统将默认该列不支持超长记录存储;

  11. 半透明列不支持带默认值的快速加列;

  12. 半透明加密列支持 UPDATE,具体规则如下:

    (1)用户通过 UPDATE 语句修改半透明加密列数据,执行提交或回滚操作前:当前用户可查询更新后表中 UID 与自身用户 ID 相匹配的半透明加密列数据,其他用户可查询更新前表中 UID 与自身用户 ID 相匹配的半透明加密列数据;

    (2)用户通过 UPDATE 语句修改半透明加密列数据,执行回滚操作后:表中数据恢复到执行 UPDATE 操作前的状态,当前用户和其他用户均可查询更新前表中 UID 与自身用户 ID 相匹配的半透明加密列数据;

    (3)用户通过 UPDATE 语句修改半透明加密列数据,执行提交操作后:当前用户和其他用户均可查询更新后表中 UID 与自身用户 ID 相匹配的半透明加密列数据。

例 1,以下是一些对表列进行半透明加密的例子。

CREATE TABLE TEST_ENCRYPT6(C1 INT, C2 INT ENCRYPT MANUAL);
CREATE TABLE TEST_ENCRYPT7(C1 INT, C2 INT ENCRYPT WITH DES_ECB MANUAL);
CREATE TABLE TEST_ENCRYPT8(C1 INT, C2 INT ENCRYPT WITH DES_ECB MANUAL HASH WITH MD5 SALT);
CREATE TABLE TEST_ENCRYPT9(C1 INT, C2 INT ENCRYPT MANUAL HASH WITH MD5 SALT);

例 2,以下是对半透明加密列进行更新操作的示例。

创建用户 USER1 和 USER2。

CREATE USER USER1 IDENTIFIED BY 123456789;
CREATE USER USER2 IDENTIFIED BY 123456789;
GRANT DBA TO USER1;
GRANT DBA TO USER2;
COMMIT;

用户 USER1 创建包含半透明加密列的表 TEST 并插入数据,执行提交操作后,用户 USER1 和 USER2 对表中数据进行查询。

CONN USER1/123456789@LOCALHOST
CREATE TABLE TEST(C1 VARCHAR ENCRYPT MANUAL);
INSERT INTO TEST VALUES('AAA');
COMMIT;
SELECT * FROM USER1.TEST;

行号   C1 
---------- ---
1     AAA
 
CONN USER2/123456789@LOCALHOST
SELECT * FROM USER1.TEST;
行号   C1 
---------- ----
1     NULL

用户 USER2 对表 TEST 中的半透明加密列进行更新,执行提交操作后,用户 USER1 和 USER2 对表中数据进行查询。

CONN USER2/123456789@LOCALHOST
UPDATE USER1.TEST SET C1 = 'BBB';
COMMIT;
SELECT * FROM USER1.TEST;

行号   C1 
---------- ---
1     BBB

CONN USER1/123456789@LOCALHOST
SELECT * FROM USER1.TEST;
行号   C1 
---------- ----
1     NULL

用户 USER1 对表 TEST 中的半透明加密列进行更新,执行回滚操作后,用户 USER1 和 USER2 对表中数据进行查询。

CONN USER1/123456789@LOCALHOST
UPDATE USER1.TEST SET C1 = 'CCC';
ROLLBACK;
SELECT * FROM USER1.TEST;

行号   C1 
---------- ----
1     NULL

CONN USER2/123456789@LOCALHOST
SELECT * FROM USER1.TEST;
行号   C1 
---------- ---

1     BBB

7.2 半透明加密

7.2.1 用户半透明加密

在 2.2 节中可以看到,创建用户时可以指定存储加密密钥,这个密钥就是为了进行半透明加密时使用的。如果在创建用户时并没有指定存储加密密钥,系统也会自动为用户生成一个默认的加密密钥。

7.2.2 表列半透明加密

如果在创建表或修改表时指定对表列进行半透明加密,DM 会使用用户的存储加密密钥对数据进行加密。半透明加密列的密文后追加了 4 个字节的 UID,用户查询数据时,若当前会话用户 ID 与列密文数据中存储的 UID 相同,则返回明文,否则返回 NULL。

建表或修改表时指定对列进半透明加密的语法格式为:

……
<列定义> ::= <不同类型列定义> [<列定义子句>]
[<STORAGE子句>] [<半透明存储加密子句>]
<半透明存储加密子句> ::= ENCRYPT [WITH <加密算法>] MANUAL[<半透明加密选项>][<散列选项>]
<半透明加密选项> ::= <半透明加密选项1> | <半透明加密选项2> | <半透明加密选项3>
<半透明加密选项1> ::= <可见用户列表>
<半透明加密选项2> ::= BY <列存储密钥> [<可见用户列表>]
<半透明加密选项3> ::= BY WRAPPED <列存储密钥的密文> [<可见用户列表>]
<可见用户列表> ::= USER ([<用户名> {,<用户名>}])
<散列选项> ::= HASH WITH <散列算法> [<加盐选项>]
<加盐选项> ::= [NO] SALT

上述语法格式不完整,主要说明与表列半透明加密相关的部分,其他建表相关语法请参考《DM8_SQL 语言使用手册》。

说明

使用半透明加密时,不同的用户可看见的数据不同。具体如下:
如果未使用<半透明加密选项>,则用户仅能查看到自己插入的数据;
如果使用了<半透明加密选项>,则只有<可见用户列表>中的用户可看见数据。

使用说明:

  1. HUGE 表不支持半透明加密列;

  2. 半透明加密列不能作为索引列,索引列也不能修改为半透明加密列;

  3. 半透明加密列不允许添加引用约束;

  4. 若表中包含半透明加密列,则不允许创建聚集索引,同时不允许删除该表原有的聚集索引;

  5. 不允许修改半透明加密列的列定义;

  6. 当增加列、删除列或者修改列定义时,若表中包含半透明加密列,则 INI 参数 ALTER_TABLE_OPT 不能设置为 1,若参数 ALTER_TABLE_OPT 为 1,则系统自动按照参数 ALTER_TABLE_OPT 为 0 时处理,关于参数 ALTER_TABLE_OPT 的详细介绍请参考手册《DM8 系统管理员手册》;

  7. 当增加列且新增列的默认值非 NULL 时,若新增列为半透明加密列,则 INI 参数 ALTER_TABLE_OPT 不能设置为 3,若参数 ALTER_TABLE_OPT 为 3,则系统自动按照参数 ALTER_TABLE_OPT 为 0 时处理;

  8. 若表中包含半透明加密列,则不允许使用 REBUILD COLUMNS 子句修改表,关于 REBUILD COLUMNS 子句的详细介绍请参考手册《DM8_SQL 语言使用手册》;

  9. 物化视图的查询语句中不能涉及半透明加密列;

  10. 若表指定了 USING LONG ROW 存储选项,即支持超长记录存储时,如果表中包含半透明加密列,并且该列的数据类型为字符串类型,则系统将默认该列不支持超长记录存储;

  11. 半透明列不支持带默认值的快速加列;

  12. 半透明加密列支持 UPDATE,具体规则如下:

    1. 用户通过 UPDATE 语句修改半透明加密列数据,执行提交或回滚操作前:当前用户可查询更新后表中 UID 与自身用户 ID 相匹配的半透明加密列数据,其他用户可查询更新前表中 UID 与自身用户 ID 相匹配的半透明加密列数据;
    2. 用户通过 UPDATE 语句修改半透明加密列数据,执行回滚操作后:表中数据恢复到执行 UPDATE 操作前的状态,当前用户和其他用户均可查询更新前表中 UID 与自身用户 ID 相匹配的半透明加密列数据;
    3. 用户通过 UPDATE 语句修改半透明加密列数据,执行提交操作后:当前用户和其他用户均可查询更新后表中 UID 与自身用户 ID 相匹配的半透明加密列数据。
  13. < 半透明加密选项 > 用于指定对当前列进行按列加密。和非按列加密的半透明加密相比,使用按列加密后,很多半透明加密规则发生了改变。例如:创建索引,修改列定义等。具体规则如下:

    1. < 半透明加密选项 > 用于指定对该列进行按列加密。< 半透明加密选项 > 缺省时,使用用户的 < 存储加密密钥 > 对列加密。其中 < 半透明加密选项 1> 使用系统自动生成的秘钥进行列加密。< 半透明加密选项 2> 和 < 半透明加密选项 3> 使用各自指定的密钥进行列加密。其中 < 半透明加密选项 2> 使用之前需先设置 INI 参数 AUTO_ENCRYPT=1,打开支持列透明加密时用户手动输入 < 列存储密钥 > 开关。按列加密的好处是将列秘钥与用户本身的密钥进行区分,可灵活设置不同的列秘钥。某个用户是否能访问按列加密的列,取决于该用户是否在指定的 < 可见用户列表 > 中;
    2. < 可见用户列表 > 用于指定该列的可见用户。按列加密的列可见性是列级的,且只对指定用户可见。指定的 < 用户名 > 必须存在且不能重复。如果 < 可见用户列表 > 缺省或者 USER 指定的用户列表为空,则表示当前列对所有用户都不可见。只有可见用户能看见加密列数据。非可见用户查看到的信息为 NULL,但是非可见用户可以对加密列进行删除、更新和插入操作;
    3. 支持将按列加密的列(即指定了 < 半透明加密选项 > 的列)作为二级索引的主键,但是不能作为聚集索引、位图索引、空间索引、数组索引和虚索引的主键。当二级索引中包含按列加密的列,且当前会话的用户不可见时,则该用户不能使用此索引进行快速过滤查询;
    4. < 列存储密钥 > 必须满足长度大于等于 INI 参数 PWD_MIN_LEN 设置的值,且包含大写、小写、数字。

例 1 以下是一些对表列进行半透明加密的例子。

CREATE TABLE TEST_ENCRYPT6(C1 INT, C2 INT ENCRYPT MANUAL);
CREATE TABLE TEST_ENCRYPT7(C1 INT, C2 INT ENCRYPT WITH DES_ECB MANUAL);
CREATE TABLE TEST_ENCRYPT8(C1 INT, C2 INT ENCRYPT WITH DES_ECB MANUAL HASH WITH MD5 SALT);
CREATE TABLE TEST_ENCRYPT9(C1 INT, C2 INT ENCRYPT MANUAL HASH WITH MD5 SALT);

例 2 以下是对半透明加密列进行更新操作的示例。

创建用户 USER1 和 USER2。

CREATE USER USER1 IDENTIFIED BY "USER1_psd";
CREATE USER USER2 IDENTIFIED BY "USER2_psd";
GRANT DBA TO USER1;
GRANT DBA TO USER2;
COMMIT;

用户 USER1 创建包含半透明加密列的表 TEST 并插入数据,执行提交操作后,用户 USER1 和 USER2 对表中数据进行查询。

CONN USER1/USER1_psd@LOCALHOST
CREATE TABLE TEST(C1 VARCHAR ENCRYPT MANUAL);
INSERT INTO TEST VALUES('AAA');
COMMIT;
SELECT * FROM USER1.TEST;
行号     C1 
---------- ---
1          AAA

CONN USER2/USER2_psd@LOCALHOST
SELECT * FROM USER1.TEST;
行号     C1  
---------- ----
1          NULL

用户 USER2 对表 TEST 中的半透明加密列进行更新,执行提交操作后,用户 USER1 和 USER2 对表中数据进行查询。

CONN USER2/USER2_psd@LOCALHOST
UPDATE USER1.TEST SET C1 = 'BBB';
COMMIT;
SELECT * FROM USER1.TEST;
行号     C1 
---------- ---
1          BBB

CONN USER1/USER1_psd@LOCALHOST
SELECT * FROM USER1.TEST;
行号     C1  
---------- ----
1          NULL

用户 USER1 对表 TEST 中的半透明加密列进行更新,执行回滚操作后,用户 USER1 和 USER2 对表中数据进行查询。

CONN USER1/USER1_psd@LOCALHOST
UPDATE USER1.TEST SET C1 = 'CCC';
ROLLBACK;
SELECT * FROM USER1.TEST;
行号     C1  
---------- ----
1          NULL

CONN USER2/USER2_psd@LOCALHOST
SELECT * FROM USER1.TEST;
行号     C1 
---------- ---
1          BBB

例 3 对表 T 的 C1 列进行按列加密。

先创建用户 USER01 和 USER02。

CREATE USER USER01 IDENTIFIED BY "USER01_psd";  
CREATE USER USER02 IDENTIFIED BY "USER02_psd";

创建 T 表,对 C1 列进行按列加密,加密列对用户 USER01 和 USER02 可见。

CREATE TABLE T(C1 INT ENCRYPT MANUAL USER (USER01,USER02));

7.3 非透明加密

DM 对非透明加密的支持是通过对用户提供加解密接口实现的。用户在使用非透明加密时,需要提供密钥并调用加解密接口。采用非透明加密可以保证个人私密数据不被包括 DBA 在内的其他人获取。

非透明加密通过用户调用存储加密函数来进行,DM 提供了一系列的存储加密函数,还提供了一个数据加密包 DBMS_OBFUSCATION_TOOLKIT。本节主要介绍 DM 的存储加密函数,关于包 DBMS_OBFUSCATION_TOOLKIT 的介绍请参看《DM8 系统包使用手册》的相关章节。

DM 提供了下列存储加密函数:

  1. CFALGORITHMSENCRYPT
CFALGORITHMSENCRYPT(
    SRC VARCHAR/TEXT/CLOB,
    ALGORITHM INT,
    KEY VARCHAR
)

参数说明:

SRC:需要被加密的数据,数据类型可以为 VARCHAR、TEXT 或 CLOB。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

功能说明:

对指定的明文进行加密,并返回密文。

当输入的参数为非法参数或者为 NULL 进而导致加密失败时,进行报错。

返回值:

加密后的密文,密文数据类型和 SRC 类型相同。

举例说明:

对数据进行加密:

CREATE TABLE enc_001(c1 VARCHAR(200));
INSERT INTO enc_001 VALUES(CFALGORITHMSENCRYPT('tt', 514, '仅供测试使用'));

这样就将加密后的数据存放到表列中。

  1. CFALGORITHMSDECRYPT
CFALGORITHMSDECRYPT(
    SRC VARCHAR/TEXT/CLOB,
    ALGORITHM INT,
    KEY VARCHAR
)

参数说明:

SRC:需要被解密的数据,数据类型可以为 VARCHAR、TEXT 或 CLOB。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

功能说明:

对密文进行解密,并得到加密前的相同数据类型的明文。

当输入的参数为非法参数或者为 NULL 进而导致解密失败时,进行报错。

返回值:

解密后的明文,明文数据类型和 SRC 类型相同。

举例说明:

对数据进行解密:

SELECT CFALGORITHMSDECRYPT(c1, 514, '仅供测试使用') FROM enc_001;
行号 			CFALGORITHMSDECRYPT(C1,514,'仅供测试使用')
---------- ------------------------------------------
1 			tt
  1. SF_ENCRYPT_BINARY
SF_ENCRYPT_BINARY(
    SRC VARBINARY,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被加密的 VARBINARY 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对 VARBINARY 类型明文进行加密,并返回密文。

当输入的参数为非法参数或者为 NULL 进而导致加密失败时,返回 NULL。

返回值:

加密后的密文,数据类型为 VARBINARY。

举例说明:

对数据进行加密:

CREATE TABLE enc_002(c1 VARBINARY(200));
INSERT INTO enc_002 VALUES(SF_ENCRYPT_BINARY(0x12345678EF, 514, '仅供测试使用', NULL));

这样就将加密后的数据存放到表列中。

  1. SF_DECRYPT_TO_BINARY
SF_DECRYPT_TO_BINARY(
    SRC VARBINARY,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被解密的 VARBINARY 类型密文。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对密文进行解密,并得到加密前的 VARBINARY 类型明文。

当输入的参数为非法参数或者为 NULL 进而导致解密失败时,返回 NULL。

返回值:

解密后的明文,数据类型为 VARBINARY。

举例说明:

对数据进行解密:

SELECT SF_DECRYPT_TO_BINARY(c1, 514, '仅供测试使用',NULL) FROM enc_002;
行号 			SF_DECRYPT_TO_BINARY(C1,514,'仅供测试使用',NULL)
---------- ------------------------------------------------
1 			0x12345678EF
  1. SF_ENCRYPT_CHAR
SF_ENCRYPT_CHAR(
    SRC VARCHAR,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被加密的 CHAR/VARCHAR 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对 VARCHAR 类型明文进行加密,并返回密文。

当输入的参数为非法参数或者为 NULL 进而导致加密失败时,返回 NULL。

返回值:

加密后的密文,数据类型为 VARBINARY。

举例说明:

对数据进行加密:

CREATE TABLE enc_003(c1 VARBINARY(200));
INSERT INTO enc_003 VALUES(SF_ENCRYPT_CHAR('测试数据', 514, '仅供测试使用',NULL));

这样就将加密后的数据存放到表列中。

  1. SF_DECRYPT_TO_CHAR
SF_DECRYPT_TO_CHAR(
    SRC VARBINARY,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被解密的 VARBINARY 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对密文进行解密,并得到加密前的 VARCHAR 类型明文。

当输入的参数为非法参数或者为 NULL 进而导致解密失败时,返回 NULL。

返回值:

解密后的明文,数据类型为 VARCHAR。

举例说明:

对数据进行解密:

SELECT SF_DECRYPT_TO_CHAR(c1, 514, '仅供测试使用',NULL) FROM enc_003;
行号 			SF_DECRYPT_TO_CHAR(C1,514,'仅供测试使用',NULL)
---------- ----------------------------------------------
1 			测试数据
  1. SF_ENCRYPT_DATE
SF_ENCRYPT_DATE(
    SRC DATE,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被加密的 DATE 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对 DATE 类型明文进行加密,并返回密文。

当输入的参数为非法参数或者为 NULL 进而导致加密失败时,返回 NULL。

返回值:

加密后的密文,数据类型为 VARBINARY。

举例说明:

对数据进行加密:

CREATE TABLE enc_004(c1 VARBINARY(200));
INSERT INTO enc_004 VALUES(SF_ENCRYPT_DATE(cast('2011-1-1' as date), 514, '仅供测试使用',NULL));

这样就将加密后的日期类型数据存放到表列中。

  1. SF_DECRYPT_TO_DATE
SF_DECRYPT_TO_DATE(
    SRC VARBINARY,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被解密的 VARBINARY 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对密文进行解密,并得到加密前的 DATE 类型明文。

当输入的参数为非法参数或者为 NULL 进而导致解密失败时,返回 NULL。

返回值:

解密后的明文,数据类型为 DATE。

举例说明:

对数据进行解密:

SELECT SF_DECRYPT_TO_DATE(c1, 514, '仅供测试使用',NULL) FROM enc_004;
行号 			SF_DECRYPT_TO_DATE(C1,514,'仅供测试使用',NULL)
---------- ----------------------------------------------
1 			2011-01-01
  1. SF_ENCRYPT_DATETIME
SF_ENCRYPT_DATETIME(
    SRC DATETIME,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被加密的 DATETIME 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对 DATETIME 类型明文进行加密,并返回密文。

当输入的参数为非法参数或者为 NULL 进而导致加密失败时,返回 NULL。

返回值:

加密后的密文,数据类型为 VARBINARY。

举例说明:

对数据进行加密:

CREATE TABLE enc_005(c1 VARBINARY(200));
INSERT INTO enc_005 VALUES(SF_ENCRYPT_DATETIME(cast('2011-12-12 11:11:11' as datetime), 514, '仅供测试使用',NULL));

这样就将加密后的日期时间类型数据存放到表列中。

  1. SF_DECRYPT_TO_DATETIME
SF_DECRYPT_TO_DATETIME(
    SRC VARBINARY,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被解密的 VARBINARY 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对密文进行解密,并得到加密前的 DATETIME 类型明文。

当输入的参数为非法参数或者为 NULL 进而导致解密失败时,返回 NULL。

返回值:

解密后的明文,数据类型为 DATETIME。

举例说明:

对数据进行解密:

SELECT SF_DECRYPT_TO_DATETIME (c1, 514, '仅供测试使用',NULL) FROM enc_005;
行号 			SF_DECRYPT_TO_DATETIME(C1,514,'仅供测试使用',NULL)
---------- --------------------------------------------------
1 			2011-12-12 11:11:11.0
  1. SF_ENCRYPT_DEC
SF_ENCRYPT_DEC(
    SRC DEC,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被加密的 DEC 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对 DEC 类型明文进行加密,并返回密文。

当输入的参数为非法参数或者为 NULL 进而导致加密失败时,返回 NULL。

返回值:

加密后的密文,数据类型为 VARBINARY。

举例说明:

对数据进行加密:

CREATE TABLE enc_006(c1 VARBINARY(200));
INSERT INTO enc_006 VALUES(SF_ENCRYPT_DEC(cast('3.1415900000'as dec(15,10)), 514, '仅供测试使用',NULL));

这样就将加密后的 DEC 数据存放到表列中。

  1. SF_DECRYPT_TO_DEC
SF_DECRYPT_TO_DEC(
    SRC VARBINARY,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被解密的 VARBINARY 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对密文进行解密,并得到加密前的 DEC 类型明文。

当输入的参数为非法参数或者为 NULL 进而导致解密失败时,返回 NULL。

返回值:

解密后的明文,数据类型为 DEC。

举例说明:

对数据进行解密:

SELECT SF_DECRYPT_TO_DEC(c1, 514, '仅供测试使用',NULL) FROM enc_006;
行号 			SF_DECRYPT_TO_DEC(C1,514,'仅供测试使用',NULL)
---------- ---------------------------------------------
1 			3.141590000000
  1. SF_ENCRYPT_TIME
SF_ENCRYPT_TIME(
    SRC TIME,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCAHR
)

参数说明:

SRC:需要被加密的 TIME 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对 TIME 类型明文进行加密,并返回密文。

当输入的参数为非法参数或者为 NULL 进而导致加密失败时,返回 NULL。

返回值:

加密后的密文,数据类型为 VARBINARY。

举例说明:

对数据进行加密:

CREATE TABLE enc_007(c1 VARBINARY(200));
INSERT INTO enc_007 VALUES(SF_ENCRYPT_TIME(cast('12:12:12' as time), 514, '仅供测试使用',NULL));

这样就将加密后的时间类型数据存放到表列中。

  1. SF_DECRYPT_TO_TIME
SF_DECRYPT_TO_TIME(
    SRC VARBINARY,
    ALGORITHM INT,
    KEY VARCHAR,
    IV VARCHAR
)

参数说明:

SRC:需要被解密的 VARBINARY 类型数据。

ALGORITHM:加密算法 ID。加密算法对应的 ID 可通过查询 V$CIPHERS 得到。

KEY:采用的密钥。

IV:采用的初始化矢量,可以为 NULL。

功能说明:

对密文进行解密,并得到加密前的 TIME 类型明文。

当输入的参数为非法参数或者为 NULL 进而导致解密失败时,返回 NULL。

返回值:

解密后的明文,数据类型为 TIME。

举例说明:

对数据进行解密:

SELECT SF_DECRYPT_TO_TIME(c1, 514, '仅供测试使用',NULL) FROM enc_007;
行号 			SF_DECRYPT_TO_TIME(C1,514,'仅供测试使用',NULL)
---------- ----------------------------------------------
1 			12:12:12.0
  1. SF_GET_CIPHER_NAME
SF_GET_CIPHER_NAME(
	CIPHER_ID IN INT
)

参数说明:

CIPHER_ID:加密算法 ID。

功能说明:

根据加密算法 ID,获取加密算法的名称。

返回值:

加密算法的名称,最大长度 32767。

举例说明:

CREATE TABLE T1(C1 INT ENCRYPT ,C2 INT ENCRYPT );
SELECT ID FROM SYSOBJECTS WHERE NAME = 'T1';
//设返回1152
SELECT * FROM SYS.SYSCOLCYT WHERE TID = 1152;
//SYSCOLCYT表中ENC_ID列对应的值,即为列的加密类型ID,此处返回2050
SELECT SF_GET_CIPHER_NAME(2050);

行号 			SF_GET_CIPHER_NAME(2050)
---------- ------------------------
1 			AES256_CBC

7.4 加密算法和散列算法

本章语法中的 < 加密算法 > 和 < 散列算法 > 既支持使用系统算法,也支持使用第三方算法。下面对支持的 < 加密算法 > 和 < 散列算法 > 进行介绍:

系统加密和散列算法

系统内置了常用的 DES、DESEDE、AES、RC4、MD5 和 SHA 等类型的加密和散列算法,以此来保护数据的安全性。DM 支持的加密算法和散列算法可通过查询动态视图 V$CIPHERS 得到,表 7.1 列出了 DM 内置的加密和散列算法。由于 DM 安装程序中自带 OPENSSL 的动态库,因此查询 V$CIPHERS 时除表 7.1 中列出的算法外,还会查询到 OPENSSL 动态库的相关算法。

DM 内置的算法中,DES、DESEDE 和 AES 为分组加密算法,RC4 为流加密算法,MD5 和 SHA 为散列算法。分组加密算法和流加密算法都是对称加密算法,加密和解密使用同一个密钥。其中,分组加密算法又称为块加密算法,分组长度又称为块大小。

DESEDE 是基于 DES 改进的加密算法,对数据进行三次加密,与 DES 相比安全性更高。AES 是相较于 DES 和 DESEDE 安全性更高的加密算法,并且支持多种长度的密钥,灵活性更高,但 DES 和 DESEDE 的加解密速度更快,因此也被广泛应用。RC4 是流加密算法,常用于加密通信协议。MD5 和 SHA 都是目前常用的散列算法,两者相比,SHA 算法的安全性较高,MD5 算法的计算速度较快。用户可根据实际应用场景选择合适的加密和散列算法。

DES、DESEDE 和 AES 算法名称中的 ECB、CBC、CFB、OFB 和 NOPAD 为分组加密的工作模式,更多说明请参考[8.1.1 算法信息相关接口](#8.1.1 算法信息相关接口)中的表 8.3。工作模式为 NOPAD 的加密算法主要用于数据页分片加密,需要用户保证原始数据长度是分组长度的整数倍,如果无法保证,则建议选择其他加密算法。

表 7.1 DM 内置的加密和散列算法

算法名称 算法类型 分组长度(单位:字节) 密钥长度(单位:字节)
DES_ECB 分组加密算法 8 8
DES_CBC 分组加密算法 8 8
DES_CFB 分组加密算法 8 8
DES_OFB 分组加密算法 8 8
DESEDE_ECB 分组加密算法 8 16
DESEDE_CBC 分组加密算法 8 16
DESEDE_CFB 分组加密算法 8 16
DESEDE_OFB 分组加密算法 8 16
DESEDE_3KEY_ECB 分组加密算法 8 24
DESEDE_3KEY_CBC 分组加密算法 8 24
DESEDE_3KEY_CFB 分组加密算法 8 24
DESEDE_3KEY_OFB 分组加密算法 8 24
AES128_ECB 分组加密算法 16 16
AES128_CBC 分组加密算法 16 16
AES128_CFB 分组加密算法 16 16
AES128_OFB 分组加密算法 16 16
AES192_ECB 分组加密算法 16 24
AES192_CBC 分组加密算法 16 24
AES192_CFB 分组加密算法 16 24
AES192_OFB 分组加密算法 16 24
AES256_ECB 分组加密算法 16 32
AES256_CBC 分组加密算法 16 32
AES256_CFB 分组加密算法 16 32
AES256_OFB 分组加密算法 16 32
DES_ECB_NOPAD 分组加密算法 8 8
DES_CBC_NOPAD 分组加密算法 8 8
DESEDE_ECB_NOPAD 分组加密算法 8 16
DESEDE_CBC_NOPAD 分组加密算法 8 16
DESEDE_3KEY_ECB_NOPAD 分组加密算法 8 24
DESEDE_3KEY_CBC_NOPAD 分组加密算法 8 24
AES128_ECB_NOPAD 分组加密算法 16 16
AES128_CBC_NOPAD 分组加密算法 16 16
AES192_ECB_NOPAD 分组加密算法 16 24
AES192_CBC_NOPAD 分组加密算法 16 24
AES256_ECB_NOPAD 分组加密算法 16 32
AES256_CBC_NOPAD 分组加密算法 16 32
RC4 流加密算法 - 16
MD5 散列算法 - -
SHA1 散列算法 - -
SHA224 散列算法 - -
SHA256 散列算法 - -
SHA384 散列算法 - -
SHA512 散列算法 - -

散列算法函数

DM 提供了散列算法函数 SF_HASH。

SF_HASH (
ID		INT,
DATA	VARBINARY/BLOB/VARCHAR/TEXT
);

参数说明:

ID:使用的散列算法 ID;

DATA:需要进行散列操作的数据。

功能说明:

对数据 DATA 进行散列,获取散列值。

返回值:

散列值,为 VARBINARY 类型。

举例说明:

SQL> SELECT SF_HASH(2432, 0xa);

执行结果如下:

行号    SF_HASH(2432,0x0A)

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

1     0xEC664E889ED6C1B2763CACF7899D95B7F347373EB982E523419FEEA3AA362D891B3BF025F292267A5854049091789C3E

第三方加密和散列算法

存储加密还支持第三方加密和散列算法,详情请参考 8 加密引擎。第三方加密算法可通过 V$EXTERNAL_CIPHERS 查看。

微信扫码
分享文档
扫一扫
联系客服