• 配置口令文件以使用区分大小写的口令
• 对表空间进行加密
• 配置对网络服务的细粒度访问
TCPS
- 安全口令支持
Oracle Database 11g中的口令:
• 区分大小写
• 包含更多的字符
• 使用更安全的散列算法
• 在散列算法中使用salt
用户名仍是Oracle 标识符(最多30 个字符,不区分大小写)。
安全口令支持
为了遵守各种安全性和隐私规定,您必须使用更安全的口令。如果口令非常短或仅包含有限的字符,则对于强力攻击就很脆弱,而包含较多不同字符的较长口令就很难被猜出或获得。在Oracle Database 11g 中,口令的处理方式与早期版本中的处理方式有所不同:
• 口令区分大小写。口令中使用的大写字符和小写字符现在是不同的字符。
• 口令可以包含未用引号括起来的多字节字符。如果口令包含除$、_或#外的任何特殊字符,则必须用引号括起来。
• 口令始终通过散列算法传递,然后作为用户身份证明进行存储。用户提供口令时,系统会对其进行散列运算,然后将其与存储的身份证明进行比较。在Oracle Database 11g中,散列算法是早期版本数据库中使用的公共算法SHA-1。SHA-1 是一种使用160 位密钥的较强算法。
• 口令始终使用salt。如果输入内容相同,散列函数将始终生成相同的输出。Salt 是添加到输入中的唯一(随机)值,用于确保输出身份证明是唯一的。
- 自动安全配置
• 默认口令概要文件
• 默认审计
• 内置口令复杂性检查
自动安全配置
Oracle Database 11g使用由Internet 安全中心(CIS) 基准推荐的特定安全功能安装和创建数据库。与10gR2 的默认安装相比,CIS 推荐的配置更安全,而且开放程度足以使大多数应用程序都能成功运行。许多客户已采用了此基准。CIS 基准的一些建议可能与一些应用程序不兼容。
- 口令配置
默认情况下:
• 启用默认口令概要文件
• 如果连续10 次登录失败,则锁定该帐户
在升级过程中:
• 口令不区分大小写(除非进行更改)
• 使用ALTER USER命令时口令区分大小写
创建时:
• 口令区分大小写
安全默认配置
使用Database Configuration Assistant (DBCA) 创建自定义数据库时,可以指定OracleDatabase 11g的默认安全配置。默认情况下,如果用户使用不正确的口令多次尝试连接Oracle 实例,则在第三次尝试后该实例将延迟每次登录。这种保护措施适用于从不同的IP地址或多个客户机进行的连接尝试。稍后,它将逐渐增加用户可以尝试其它口令的时间间隔,最长时间大约为十秒。
创建数据库时,将启用具有如下设置的默认口令概要文件:
PASSWORD_LIFE_TIME 180
PASSWORD_GRACE_TIME 7
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LOCK_TIME 1
PASSWORD_VERIFY_FUNCTION NULL
Oracle Database 10g数据库升级后,只有使用ALTER USER…命令更改口令后,口令才会区分大小写。
创建数据库时,默认情况下口令区分大小写。
- 启用内置口令复杂性检查器
执行utlpwdmg.sql脚本创建口令验证功能:
SQL> CONNECT / as SYSDBA
SQL> @?/rdbms/admin/utlpwdmg.sql
更改默认概要文件:
ALTER PROFILE DEFAULT LIMIT
PASSWORD_VERIFY_FUNCTION verify_function_11g;
启用内置口令复杂性检查器
verify_function_11g是一个PL/SQL 功能示例,可以轻松进行修改以在您的站点中强制实行口令复杂性策略。此功能不需要在口令中嵌入特殊字符。
verify_function_11g和较早的verify_function都包含在utlpwdmg.sql文件中。
要启用口令复杂性检查,请创建一个归SYS所有的验证功能。可使用提供的一个功能或对其中的一个进行修改来满足您的要求。此示例显示了如何使用utlpwdmg.sql脚本。
如果概要文件中命名的口令复杂性检查功能中存在错误或此功能不存在,则不能更改口令,也不能创建用户。解决方法是在概要文件中将PASSWORD_VERIFY_FUNCTION设置为NULL,直到问题得到解决。
verify_function_11g功能将检查口令是否至少包含八个字符、是否至少包含一个数字和一个字母字符,以及是否至少有三个字符与以前口令不同。该函数还确认此口令不是以下项:用户名或附加了1 到100 之间任何数字的用户名、反向的用户名、服务器名或附加了1 到100 之间数字的服务器名,或者一组众所周知的常用口令,如“welcome1”、“database1”、“oracle123”或“oracle(附加了1 到100 之间的数字)”等。
- 管理默认审计
检查审计日志:默认的审计选项涵盖了重要的安全权限。
归档审计记录:
• 导出
• 复制到其它表
删除归档审计记录。
管理默认审计
检查审计日志。默认情况下,在Oracle Database 11g中将为对安全性非常重要的特定权限启用审计。审计线索默认记录在数据库AUD$表中,AUDIT_TRAIL参数设置为DB。对于大多数站点而言,这些审计不会对数据库性能造成太大影响。Oracle 建议使用操作系统
审计线索文件。
归档审计记录。要保留审计记录,请使用Oracle 数据泵导出实用程序将其导出,或者使用SELECT语句将一组审计记录捕获到单独的表中。
删除归档审计记录。在检查并归档审计记录后,会从SYS.AUD$表中将其删除。审计记录将占用SYSTEM表空间中的空间。如果SYSTEM表空间无法增长,则无法为审计记录提供更多空间,此时会针对每条审计语句生成错误。由于CREATE SESSION是已审计的权限之一,所以不能创建新的会话(除非用户以SYSDBA身份连接)。可使用QUERY选项指定带有日期范围或SCN 范围的WHERE子句,通过导出实用程序归档审计表。然后,使用相同的WHERE子句从审计表中删除这些记录。
当AUDIT_TRAIL=OS时,会在由AUDIT_FILE_DEST指定的目录中为每条审计记录创建单独的文件。可以复制特定时间之前的所有文件,然后删除它们。
注:SYSTEM表空间是使用autoextend on选项创建的。因此SYSTEM表空间可以根据需要增长,直到用尽磁盘上的可用空间。
系统会按照访问针对成功和失败的操作审核所有用户的以下权限:
CREATE EXTERNAL JOB
CREATE ANY JOB
GRANT ANY OBJECT PRIVILEGE
EXEMPT ACCESS POLICY
CREATE ANY LIBRARY
GRANT ANY PRIVILEGE
DROP PROFILE
ALTER PROFILE
DROP ANY PROCEDURE
ALTER ANY PROCEDURE
CREATE ANY PROCEDURE
ALTER DATABASE
GRANT ANY ROLE
CREATE PUBLIC DATABASE LINK
DROP ANY TABLE
ALTER ANY TABLE
CREATE ANY TABLE
DROP USER
ALTER USER
CREATE USER
CREATE SESSION
AUDIT SYSTEM
ALTER SYSTEM
SYSTEM AUDIT
ROLE
- 调整安全性设置
调整安全性设置
使用DBCA 工具创建数据库时,可以选择以下安全性设置:
• 保留11g的默认增强安全设置(建议)。这些设置包括启用审计和新的默认口令概要文件。
• 还原到11g之前的默认安全设置。要禁用特定类别的增强设置以实现兼容性,请选择以下设置:
- 将审计设置还原为11g之前的默认设置
- 将口令概要文件设置还原为11g之前的默认设置
也可以使用DBCA 在创建数据库后更改这些设置。在11g的默认安全设置下,有些应用程序可能无法正常运行。
应始终设置安全的软件权限。它不受用户选择的“Security Settings(安全设置)”选项所影响。
- 设置安全性参数
• 使用区分大小写的口令:
SEC_CASE_SENSITIVE_LOGON
• 防止DoS 攻击:
SEC_PROTOCOL_ERROR_FURTHER_ACTION
SEC_PROTOCOL_ERROR_TRACE_ACTION
• 防止强力攻击:
SEC_MAX_FAILED_LOGIN_ATTEMPTS
设置安全性参数
Oracle Database 11g增加了一组新参数以加强数据库的默认安全性。这些参数是系统范围的静态参数。
使用区分大小写的口令以加强安全性
新参数SEC_CASE_SENSITIVE_LOGON使您可以设置区分大小写的用户口令。Oracle 建议保留默认设置TRUE。将此参数设置为FALSE可指定不区分大小写的口令以实现向后兼容性。
ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = FALSE
注:禁用区分大小写会使口令在强力攻击面前变得更脆弱。
防止拒绝服务(DoS) 攻击
本示例中列出的两个参数指定了当数据库从客户机处收到损坏的数据包时要执行的操作。假设损坏的数据包来自可能的恶意客户机。
SEC_PROTOCOL_ERROR_FURTHER_ACTION参数指定了要对客户机连接执行的操作:继续、断开连接或延迟接受请求。另一参数SEC_PROTOCOL_ERROR_TRACE_ACTION指定了监视操作:NONE、TRACE、LOG或ALERT。
防止强力攻击
新的初始化参数SEC_MAX_FAILED_LOGIN_ATTEMPTS的默认设置为10,表示在连接尝试达到指定次数后会自动断开连接。即使未启用口令概要文件,也会强制实施此参数。此参数可以防止程序连接到数据库,然后成百上千次地尝试口令以通过验证。
- 设置数据库管理员验证
使用带有区分大小写的口令的口令文件。
对管理员角色启用严格的验证:
• 在OID 中授予管理员角色。
• 使用Kerberos 票证。
• 使用SSL 证书。
设置数据库管理员验证
数据库管理员必须经过验证。在Oracle Database 11g中,可以使用新的方法来更安全地执行管理员验证并集中管理这些已授权的用户。此外,区分大小写的口令还应用于已授权用户的远程连接上。可使用下列命令覆盖此默认行为:
orapwd file=orapworcl entries=5 ignorecase=Y
如果担心口令文件易受破坏或难以维护许多口令文件,则可以实施严格验证:
• 在Oracle Internet Directory (OID) 中授予SYSDBA或SYSOPER企业角色。
• 使用Kerberos 票证
• 使用SSL 证书
要使用严格验证方法,必须将所有LDAP_DIRECTORY_SYSAUTH初始化参数设置为YES。将此参数设置为NO可禁用严格验证方法。通过OID 或Kerberos 进行的验证还能提供集中管理或单一登录功能。
如果配置了口令文件,则可先对其进行检查。用户也可以作为OSDBA或OSOPER组的成员由本地操作系统进行验证。
- 透明数据加密
TDE 中的新增功能包括:
• 表空间加密
• 支持LogMiner
• 支持逻辑备用
• 支持流
• 支持异步更改数据捕获
• 基于硬件的主密钥保护
透明数据加密
一些新增功能可增强透明数据加密(TDE) 功能,这些功能是基于相同的基础结构构建的。
为支持TDE 而对LogMiner 所做的更改提供了用于更改捕获引擎的基础结构,这些引擎可用于逻辑备用、流和异步更改数据捕获。要让LogMiner 支持TDE,它必须能够访问加密Wallet。要访问该Wallet,必须装载实例并使Wallet 处于开启状态。LogMiner不支持硬件安全模块(HSM) 或用户持有密钥。
对于逻辑备用,可在源或目标数据库挖掘日志,因此用于这两个数据库的Wallet必须相同。
加密列的处理方式在流和基于流的更改数据捕获中均相同。将在Wallet 所在的源中挖掘重做记录。数据以未加密的方式传输到目标位置,然后在目标位置使用Wallet 进行加密。该数据可以使用高级安全选项在传输中进行加密以实现网络加密。
- 使用表空间加密
创建加密的表空间。
1. 创建或打开加密Wallet:
SQL> ALTER SYSTEM SET ENCRYPTION KEY IDENTIFIED BY "welcome1";
2. 使用加密关键字创建表空间:
SQL> CREATE TABLESPACE encrypt_ts
2> DATAFILE '$ORACLE_HOME/dbs/encrypt.dat' SIZE 100M
3> ENCRYPTION USING '3DES168'
4> DEFAULT STORAGE (ENCRYPT);
表空间加密
表空间加密以在写入时进行加密并在读取时进行解密的块级别加密技术为基础,并不在内存中对数据进行加密。影响加密的唯一因素与I/O 相关联。SQL 访问路径不变,并且支持所有数据类型。要使用表空间加密,加密Wallet 必须处于开启状态。
CREATE TABLESPACE命令包含一个用于设置加密属性的ENCRYPTION子句,以及一个导致使用加密的ENCRYPT存储参数。您可以指定USING 'encrypt_algorithm'来指示要使用的算法名称。有效的算法包括3DES168、AES128、AES192 和AES256。默认算法为AES128。可以在V$ENCRYPTED_TABLESPACES视图中查看这些属性。
加密的数据在执行操作(如JOIN和SORT)期间会受到保护。这意味着数据在移动到临时表空间时是安全的。还原日志和重做日志中的数据也受到保护。
如果平台有相同的Endianess 和Wallet,则加密的表空间是可移动的。
限制
• 无法对临时表空间和还原表空间进行加密(所选的块已加密)。
•Bfiles 和外部表未加密。
• 不支持跨不同的endian 平台移动表空间。
• 当前无法更改加密表空间的密钥。解决方法是:使用所需的属性创建一个表空间,然后将所有对象移动到新建的表空间中。
- 硬件安全模块
硬件安全模块
硬件安全模块(HSM) 是一种物理设备,可以安全地存储加密密钥。它还可以提供安全的计算空间(内存)以执行加密和解密操作。HSM 是Oracle wallet 的一种更安全的代替方法。
透明数据加密(TDE) 可使用HSM 来加强敏感数据的安全性。HSM 用于存储TDE 使用的主加密密钥。因为HSM 是一种物理设备而不是一个操作系统文件,所以在未授权的访问尝试中密钥是安全的。使用主加密密钥的所有加密和解密操作都在HSM 中执行。这意味着主加密密钥永远不会在不安全的内存中公开。
有些供应商可提供硬件安全模块,这些供应商还必须提供相应的库。
- LOB 列的加密
• LOB 加密只能用于SECUREFILE LOB。
• LOB 列中的所有LOB 都已加密。
• 可以按列或按分区对LOB 进行加密。
– SECUREFILELOB 和BASICFILELOB 可以共存
CREATE TABLE test1 (doc CLOB ENCRYPT USING 'AES128')
LOB(doc) STORE ASSECUREFILE (CACHE NOLOGGING );
LOB 列的加密
Oracle Database 11g 引入了一个经过完全重新设计的大对象(LOB) 数据类型,此类型显著提高了应用程序开发的效率和可管理性,并简化了应用程序的开发过程。LOB 的这种Secure Files 实施提供了下一代的高级功能,如智能压缩和透明加密。Secure Files 中的加密数据会就地存储并可以随机进行读取和写入。
必须使用SECUREFILE参数创建LOB,并对LOB 列启用加密(ENCRYPT)或禁用加密(DECRYPT,默认值)。可使用当前的TDE 语法将加密扩展到LOB 数据类型。
系统仍支持早期版本中的LOB 实施以实现向后兼容性,但现在将其称为Basic Files。如果将LOB 列添加到一个表中,则可以指定将其创建为SECUREFILES还是
BASICFILES。为了确保向后兼容性,默认的LOB 类型为BASICFILES。
有效算法包括3DES168、AES128、AES192 和AES256。默认算法为AES192。
- Enterprise Manager 安全管理
通过EM 管理安全性。
• 对于以下项取代了Policy Manager:
– 虚拟专用数据库
– 应用程序上下文
– Oracle Label Security
• 添加了“Enterprise User Security(企业用户安全性)”页
• 添加了TDE 页
Enterprise Manager 安全管理
安全管理功能已集成到Enterprise Manager 中。
该功能取代了基于Policy Manager Java 控制台的工具。以前通过Oracle Policy Manager 工具管理的Oracle Label Security、应用程序上下文和虚拟专用数据库现在通过Enterprise Manager 即可进行管理,但Oracle Policy Manager 工具仍然可用。
Enterprise Manager Security 工具已由Enterprise Manager 功能取代。现在Enterprise User Security 也可通过Enterprise Manager 进行管理。ldap.ora文件配置完成后,会立即显示Enterprise Manager 的菜单项。Enterprise Manager Security 工具仍然可用。
TDE 现在可通过Enterprise Manager 进行管理,包括Wallet 管理。可以从Enterprise Manager 页中创建、打开和关闭Wallet。
- 使用RMAN 安全性增强功能
• 配置备份粉碎功能:
RMAN> CONFIGURE ENCRYPTION FOR DATABASE ON;
• 使用备份粉碎功能:
RMAN> DELETE FORCE;
使用RMAN 安全性增强功能
备份粉碎是一项重要的管理功能,它使DBA可以删除透明加密备份的加密密钥,而无需以物理方式访问备份介质。如果加密密钥被破坏,则加密备份将是无法访问的,这不适用于受口令保护的备份。
可使用以下命令配置透明加密备份:
CONFIGURE ENCRYPTION FOR DATABASE ON;
或
SET ENCRYPTION ON;
默认设置为OFF,不启用备份粉碎功能。要粉碎备份,无需使用新命令,只需使用:DELETE FORCE;
- 管理对外部网络服务的细粒度访问
1.创建ACL 及其权限:
BEGIN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
acl => 'us-oracle-com-permissions.xml',
description => 'Permissions for oracle network',
principal => 'SCOTT',
is_grant => TRUE,
privilege => 'connect');
END;
通过PL/SQL 程序包的网络实用程序系列(如UTL_TCP、UTL_INADDR、UTL_HTTP、UTL_SMTP和UTL_MAIL),Oracle 用户可以使用原始TCP 或基于原始TCP 创建的更高级别协议从数据库进行网络调出。无论用户是否具有对这些程序包的EXECUTE权限,都无法控制所访问的网络主机。新的程序包DBMS_NETWORK_ACL_ADMIN支持使用XML DB 实施的访问控制列表(ACL) 进行细粒度控制。
1.创建访问控制列表(ACL)。ACL 是在XML 文件中保存的用户和权限的列表。以acl参数命名的XML 文档与XML DB中的/sys/acl/文件夹相关。在本示例中,SCOTT被授予connect权限。ACL 中的用户名区分大小写,而且必须与会话的用户名相匹配。只有resolve和connect权限,connect权限包含
resolve权限。可选参数可以指定这些权限的开始和结束时间戳。要将更多用户和权限添加到此ACL 中,请使用ADD_PRIVILEGE过程。
2.将ACL 分配给一台或多台网络主机:
BEGIN
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
acl => 'us-oracle-com-permissions.xml',
host => '*.us.oracle.com',
lower_port => 80,
upper_port => null);
END
2.将ACL分配给一台或多台网络主机。ASSIGN_ACL过程将ACL 与一台网络主机和一个端口或端口范围(可选)相关联。在该示例中,主机参数允许使用主机名通配符将ACL 分配给域中的所有主机。使用通配符会影响ACL 评估的优先级顺序。端口的相应完全限定主机名在端口的相应主机前进行评估。完全限定的主机名在部分域名前进行评估,子域在顶级域之前进行评估。
创建ACL 后,可以将多台主机分配到同一ACL 中,还可以将多个用户按任意顺序添加到同一ACL 中。
- 小结
• 配置口令文件以使用区分大小写的口令
• 对表空间进行加密
• 配置对网络服务的细粒度访问
说明
Oracle加密技术主要分为两种,一种是使用包DBMS_CRYPTO来加密解密应用数据,另一个是透明加密技术(TDE,Oracle10.2开始)。
前者针对应用程序数据加密,应用程序或者函数的调用者必须提供加密秘钥,支持类型限制较多,对数据库整体性能、数据安全(登录到数据库或者提取数据文件都是查看到相关数据的明文)意义不大。
后者主要针对对象存储在数据文件中的内容加密,或直接表空间加密,应用无需调整,推荐使用表空间透明加密,限制较少。如使用加密技术,需定期备份钱包,避免因外部存储设备损坏造成秘钥丢失,影响数据库数据正常使用。
目前Oracle不支持其他加密算法,对数据库本身性能影响较小、限制较小为表空间的透明加密。
两种加密,具体介绍如下:
DBMS_CRYPTO简单介绍
DBMS_CRYPTO提供用于加密和解密存储的数据的接口,并且可以与运行网络通信的PL / SQL程序结合使用。它支持多种行业标准的加密和哈希算法,包括高级加密标准(AES)加密算法。AES已获得美国国家标准技术研究院(NIST)的批准,以取代数据加密标准(DES)。
支持以下加密算法:
数据加密标准(DES),三重DES(3DES,2键和3键)
高级加密标准(AES)
MD5,MD4和SHA-1加密哈希
MD5和SHA-1消息认证码(MAC)
限制:
该VARCHAR2数据类型不直接支持DBMS_CRYPTO。在对类型的数据执行加密操作之前VARCHAR2,必须将其转换为统一的数据库字符集AL32UTF8,然后将其转换为RAW数据类型。完成这些转换后,您可以使用DBMS_CRYPTO程序包对其进行加密。
密钥管理是程序化的。也就是说,应用程序(或函数的调用者)必须提供加密密钥。这意味着应用程序开发人员必须找到一种安全地存储和检索密钥的方法。该DBMS_OBFUSCATION_TOOLKIT程序包(不推荐使用,替代者是DBMS_CRYPTO)可以处理字符串和原始数据,需要提交64位密钥。DES算法本身的有效密钥长度为56位。
举例
--AES 256数据加密解密 declare input_string VARCHAR2 (200) := 'Secret Message'; output_string VARCHAR2 (200); encrypted_raw RAW (2000); -- stores encrypted binary text decrypted_raw RAW (2000); -- stores decrypted binary text num_key_bytes NUMBER := 256/8; -- key length 256 bits (32 bytes) key_bytes_raw RAW (32); -- stores 256-bit encryption key encryption_type PLS_INTEGER := -- total encryption type DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5; begin DBMS_OUTPUT.PUT_LINE ('Original string: ' || 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 ); -- The encrypted value in the encrypted_raw variable can be used here: 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 ('Decrypted string: ' || output_string); end;
BLOB的数据加密解密。
- 创建一个有BLOB列的表
- 插入raw值
- 加密raw
- 解密数据
- 1. Create a table for BLOB column: create table table_lob (id number, loc blob); -- 2. Insert 3 empty lobs for src/enc/dec: insert into table_lob values (1, EMPTY_BLOB()); insert into table_lob values (2, EMPTY_BLOB()); insert into table_lob values (3, EMPTY_BLOB()); set echo on set serveroutput on declare srcdata RAW(1000); srcblob BLOB; encrypblob BLOB; encrypraw RAW(1000); encrawlen BINARY_INTEGER; decrypblob BLOB; decrypraw RAW(1000); decrawlen BINARY_INTEGER; leng INTEGER; begin -- RAW input data 16 bytes srcdata := hextoraw('6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D'); dbms_output.put_line('---'); dbms_output.put_line('input is ' || srcdata); dbms_output.put_line('---'); -- select empty lob locators for src/enc/dec select loc into srcblob from table_lob where id = 1; select loc into encrypblob from table_lob where id = 2; select loc into decrypblob from table_lob where id = 3; dbms_output.put_line('Created Empty LOBS'); dbms_output.put_line('---'); leng := DBMS_LOB.GETLENGTH(srcblob); IF leng IS NULL THEN dbms_output.put_line('Source BLOB Len NULL '); ELSE dbms_output.put_line('Source BLOB Len ' || leng); END IF; leng := DBMS_LOB.GETLENGTH(encrypblob); IF leng IS NULL THEN dbms_output.put_line('Encrypt BLOB Len NULL '); ELSE dbms_output.put_line('Encrypt BLOB Len ' || leng); END IF; leng := DBMS_LOB.GETLENGTH(decrypblob); IF leng IS NULL THEN dbms_output.put_line('Decrypt BLOB Len NULL '); ELSE dbms_output.put_line('Decrypt BLOB Len ' || leng); END IF; -- 3. Write source raw data into blob: DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite); DBMS_LOB.WRITEAPPEND (srcblob, 16, srcdata); DBMS_LOB.CLOSE (srcblob); dbms_output.put_line('Source raw data written to source blob'); dbms_output.put_line('---'); leng := DBMS_LOB.GETLENGTH(srcblob); IF leng IS NULL THEN dbms_output.put_line('source BLOB Len NULL '); ELSE dbms_output.put_line('Source BLOB Len ' || leng); END IF; /* * Procedure Encrypt * Arguments: srcblob -> Source BLOB * encrypblob -> Output BLOB for encrypted data * DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES * Chaining : CBC * Padding : PKCS5 * 256 bit key for AES passed as RAW * -> hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F') * IV (Initialization Vector) for AES algo passed as RAW * -> hextoraw('00000000000000000000000000000000') */ DBMS_CRYPTO.Encrypt(encrypblob, srcblob, DBMS_CRYPTO.AES_CBC_PKCS5, hextoraw ('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'), hextoraw('00000000000000000000000000000000')); dbms_output.put_line('Encryption Done'); dbms_output.put_line('---'); leng := DBMS_LOB.GETLENGTH(encrypblob); IF leng IS NULL THEN dbms_output.put_line('Encrypt BLOB Len NULL'); ELSE dbms_output.put_line('Encrypt BLOB Len ' || leng); END IF; -- 4. Read encrypblob to a raw: encrawlen := 999; DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.READ (encrypblob, encrawlen, 1, encrypraw); DBMS_LOB.CLOSE (encrypblob); dbms_output.put_line('Read encrypt blob to a raw'); dbms_output.put_line('---'); dbms_output.put_line('Encrypted data is (256 bit key) ' || encrypraw); dbms_output.put_line('---'); /* * Procedure Decrypt * Arguments: encrypblob -> Encrypted BLOB to decrypt * decrypblob -> Output BLOB for decrypted data in RAW * DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES * Chaining : CBC * Padding : PKCS5 * 256 bit key for AES passed as RAW (same as used during Encrypt) * -> hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F') * IV (Initialization Vector) for AES algo passed as RAW (same as used during Encrypt) * -> hextoraw('00000000000000000000000000000000') */ DBMS_CRYPTO.Decrypt(decrypblob, encrypblob, DBMS_CRYPTO.AES_CBC_PKCS5, hextoraw ('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'), hextoraw('00000000000000000000000000000000')); leng := DBMS_LOB.GETLENGTH(decrypblob); IF leng IS NULL THEN dbms_output.put_line('Decrypt BLOB Len NULL'); ELSE dbms_output.put_line('Decrypt BLOB Len ' || leng); END IF; -- Read decrypblob to a raw decrawlen := 999; DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.READ (decrypblob, decrawlen, 1, decrypraw); DBMS_LOB.CLOSE (decrypblob); dbms_output.put_line('Decrypted data is (256 bit key) ' || decrypraw); dbms_output.put_line('---'); DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite); DBMS_LOB.TRIM (srcblob, 0); DBMS_LOB.CLOSE (srcblob); DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.TRIM (encrypblob, 0); DBMS_LOB.CLOSE (encrypblob); DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.TRIM (decrypblob, 0); DBMS_LOB.CLOSE (decrypblob); end; / truncate table table_lob; drop table table_lob;
3. 透明加密介绍
3.1 概述
透明数据加密(TDE)使您可以加密存储在表和表空间中的敏感数据,例如信用卡号。对有权访问数据的数据库用户或应用程序
透明地解密加密的数据。如果存储介质或数据文件被盗,TDE有助于保护存储在介质上的数据。
说明:秘钥通过钱包管理,具体说明可参见本文钱包相关说明。加密后,没有钱包,无法直接获取数据文件中的数据。如果wallet文件丢失,没有办法open钱包,也就是说加密数据无法读取.备份ewallet.p12文件非常重要。
透明数据加密(TDE)具有以下优点:
- 作为安全管理员,您可以确保敏感数据是安全的,以防存储媒体或数据文件被盗。
- 实施TDE可帮助您解决与安全相关的法规遵从性问题。
- 您无需创建触发器或视图即可为授权用户或应用程序解密数据。表中的数据为数据库用户和应用程序透明地解密。
- 数据库用户和应用程序不必知道他们正在访问的数据是以加密形式存储的事实。对数据库用户和应用程序透明地解密数据。
- 无需修改应用程序即可处理加密数据。数据加密和解密由数据库管理。
- 密钥管理操作是自动化的。用户或应用程序不需要管理加密密钥。
3.2 透明加密的类型
透明数据加密(TDE)列加密使您能够加密存储在选择表列中的敏感数据。TDE表空间加密使您可以加密存储在表空间中的所有数据。
TDE列加密和TDE表空间加密都使用基于密钥的两层体系结构。即使检索到加密数据,也无法理解,直到发生授权解密为止,这对于授权访问该表的用户是自动的。
列的加密过程
如上图所示,主加密密钥存储在数据库外部的外部安全模块中,并且只能由安全管理员访问。对于此外部安全模块,Oracle使用Oracle钱包或硬件安全模块(HSM),如本章所述。以这种方式存储主加密密钥可以防止未经授权的使用。
使用外部安全模块(钱包/ HSM)可以将常规程序功能与加密操作分开,从而可以在数据库管理员和安全管理员之间划分职责。由于数据库管理员可以知道钱包密码,因此需要安全管理员提供密码,从而增强了安全性。
当表包含加密列时,无论加密列的数量如何,都将使用单个表密钥。所有表的表密钥均使用数据库服务器主加密密钥加密,并存储在数据库的字典表中。没有密钥存储在明文中。
- B树以外的索引类型
- 通过索引进行范围扫描搜索
- 外部大对象(BFILE)
- 同步更改数据捕获
- 传输表空间
- 原始导入/导出实用程序
- 此外,您不能使用TDE列加密来加密外键约束中使用的列。
表空间加密过程
TDE表空间加密的限制:
- BFILE不能使用TDE表空间加密来加密外部大对象。这是因为这些文件位于数据库外部。
- 要执行导入和导出操作,请使用Oracle Data Pump。
--1 使用钱包(wallet)作为外部安全模块,保存主密钥 --oracle建议对TDE使用一个单独的的钱包 --在sqlnet.ora中使用参数 ENCRYPTION_WALLET_LOCATION指定钱包的位置 ENCRYPTION_WALLET_LOCATION= (SOURCE=(METHOD=FILE)(METHOD_DATA= (DIRECTORY=/u02/app/oracle/product/11.2.0/dbhome_1/wallet))) --生成主密钥 SQL> ALTER SYSTEM SET ENCRYPTION KEY IDENTIFIED BY "oracle123"; --打开关闭钱包 SQL> ALTER SYSTEM SET ENCRYPTION WALLET OPEN IDENTIFIED BY "oracle123"; SQL> ALTER SYSTEM SET ENCRYPTION WALLET CLOSE IDENTIFIED BY "oracle123"; V$ENCRYPTION_WALLET displays information on the status of the wallet and the wallet location for TDE --重置主密钥 ALTER SYSTEM SET ENCRYPTION KEY IDENTIFIED BY "oracle321"; --数据库只有读取钱包中的主密钥才能加密解密数据 默认情况下,TDE 使用具有192位密钥长度 (AES192) 的 AES 加密算法。可以指定非默认加密算法 默认情况下,TDE使用salt选项,加密之前将随机码添加到明文,这样很难破解加密。可以使用no salt取消随机码添加 默认情况下,TDE使用SHA-1完整性算法生成Authentication Code (MAC),做完整性检查。可以使用nomac取消完整性检查, 这样会提高性能节省存储空间。 --注意:可以将钱包配置为autologin方式 --2 列加密 --启用列加密 CREATE TABLE em ( first_name VARCHAR2(128), last_name VARCHAR2(128), empid NUMBER, salary NUMBER(6) ENCRYPT ); --使用非默认加密算法 CREATE TABLE emp ( first_name VARCHAR2(128), last_name VARCHAR2(128), empid NUMBER, salary NUMBER(6) ENCRYPT USING '3DES168' NO SALT ); SQL> ALTER TABLE emp MODIFY (first_name ENCRYPT); --注意:在加密列上创建索引,加密列不能使用salt方式 SQL> ALTER TABLE employee MODIFY (first_name ENCRYPT NO SALT); create index first_name_indx on emp (first_name); --取消列加密 SQL> ALTER TABLE employee MODIFY (first_name DECRYPT); --3 表空间加密 --启用表空间加密 CREATE TABLESPACE securespace2 DATAFILE '/u02/app/oracle/secure01.dbf' SIZE 10M ENCRYPTION DEFAULT STORAGE(ENCRYPT); --DBA_TABLESPACES: The ENCRYPTED column indicates whether a tablespace is encrypted-- --USER_TABLESPACES: The ENCRYPTED column indicates whether a tablespace is encrypted --注意:You cannot access any encrypted data without the master encryption key --》管理TDE 1 启用AUTO LOGIN wallet --2 备份和管理主密钥 --如果没有主密钥是不能访问加密数据的,主密钥存储在wallet中,需要对wallet做备份 --当产生新的主密钥时必须备份wallet --备份时不应同时备份加密数据和钱包wallet,应单独备份wallet,以防止恶意用户同时获取加密数据和wallet钱包 --rman不会备份wallet --rman如果使用了Oracle Secure Backup OSB(如带库)会自动排除auto login wallet(cwallet.sso), 但不会排除普通的wallet(ewallet.p12 ),所以使用此备份方式,建议添加以下语句排除wallet exclude name *.p12 --如果存储主密钥的wallet丢失或损坏,将备份版本拷贝至适当位置即可恢复 --1 如果备份版本是上次重置主密钥之后版本,无需任何操作 --2 如果备份版本是上次重置主密钥之前版本,即不包含最新主密钥,则需要将数据库恢复至重置主密钥之前时间点。 之后的数据将丢失。 ================================ --》其他加密 --加密数据无法使用exp/imp工具移动,只能使用datapump移动数据, --导出TDE加密 数据时,必须打开钱包wallet,因为数据需要主密钥解密 --使用数据泵datapump或恢复管理器rman移动数据时,如果使用TDE加密功能,需要wallet。 也可以使用工具自带的加密功能单独加密数据。 --数据泵(datapump)加密 --1 涉及TDE数据时,需要wallet钱包打开,只适合本机原地操作。 --导出数据后,数据以非加密的形式存储在转储文件集中 expdp hr/hr TABLES=emp DIRECTORY=DATA_PUMP_DIR DUMPFILE=emp.dmp logfile=emp.expdp ORA-39173: Encrypted data has been stored unencrypted in dump file set. ALTER SYSTEM SET ENCRYPTION WALLET CLOSE IDENTIFIED BY "oracle123"; impdp \'/ as sysdba\' DIRECTORY=DATA_PUMP_DIR DUMPFILE=emp.dmp logfile=emp.impdp remap_schema=hr:test --如果想转储文件集也加密,可以单独指定以下参数(TDE数据解密后再加密) ENCRYPTION_PASSWORD ENCRYPTION = [ALL | DATA_ONLY | ENCRYPTED_COLUMNS_ONLY | METADATA_ONLY | NONE] ALL enables encryption for all data and metadata in the export operation. DATA_ONLY specifies that only data is written to the dump file set in encrypted format. ENCRYPTED_COLUMNS_ONLY specifies that only encrypted columns are written to the dump file set in encrypted format. To use this option, you must have Oracle Advanced Security transparent data encryption enabled. See Oracle Database Advanced Security Administrator is Guide for more information about transparent data encryption. METADATA_ONLY specifies that only metadata is written to the dump file set in encrypted format. NONE specifies that no data is written to the dump file set in encrypted format. ENCRYPTION不指定默认为all --2 不涉及TDE数据时,不需要wallet钱包,可单独加密转储文件集。适用于所有场景 expdp hr/hr TABLES=employees DIRECTORY=DATA_PUMP_DIR DUMPFILE=employees.dmp logfile=employees.expdp encryption_password=oracle --impdp \'/ as sysdba\' DIRECTORY=DATA_PUMP_DIR DUMPFILE=employees.dmp logfile=employees.impdp remap_schema=hr:test ORA-39174: Encryption password must be supplied. encryption_password=oracle --RMAN备份加密 --1 使用TDE,适合本机原地操作 --1)创建钱包(已创建) --2)打开钱包 SQL> alter system set encryption wallet open identified by oracle; --3)开启RMAN加密功能 RMAN> configure encryption for database on; --4)备份与恢复命令不会发生更改,需要打开钱包 --5)通过命令可以暂时覆盖永久配置 RMAN> set encryption off; --2 口令模式设置(不需要钱包),使用与所有场景 RMAN> set encryption on identified by admin only; RMAN> backup datafile 4; RMAN> set decryption identified by admin; --还原时必须解密 RMAN> restore datafile 4; --3 如果创建了钱包,可以使用双重模式 SQL> alter system set encryption wallet open identified by oracle; RMAN> set encryption on identified by oracle; RMAN> backup datafile 4; SQL> alter system set encryption wallet close; --关闭钱包 RMAN> set decryption identified by oracle; --钱包、口令任选一个 SQL> alter system set encryption wallet open identified by oracle; RMAN> restore datafile 4; RMAN> recover datafile 4; RMAN> alter database open; --改变rman加密算法 SQL> select algorithm_name from v$rman_encryption_algorithms; RMAN> configure encryption algorithm 'AES192'; RMAN> set encryption algorithm 'AES256'; --relate view --在dba_tablespaces会添加新列encrypted让你查看状态 v$encryption_wallet v$encrypted_tablespaces
钱包管理说明
Oracle钱包管理器(Wallet Manager),管理客户端或服务器上公共密钥(public key )的安全认证。数据库可以读取钱包中的密钥。
Oracle钱包(wallet)是一个可以存储认证和证书的安全软件,Oracle钱包(wallet)也可作为安全的外部密码存储区,使用此特性后,应用程序,脚本等都不需要写出用户名密码即可连接数据库。降低了密码泄露的风险。
Wallet 可以使用Oracle Wallet Manger工具来创建,也可以使用orapki 命令来创建,也可以使用SQL 语句来创建。这里最方便的是使用SQL语句。
-- 在sqlnet.ora 文件里添加: ENCRYPTION_WALLET_LOCATION 和WALLET_LOCATION参数。 默认位置是:$ORACLE_BASE/admin/$ORACLE_SID/wallet。 --指定ORACLE WALLET的位置,这里使用ORACLE_HOME/network/admin,在sqlnet.ora里添加如下内容: WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY= /u01/app/oracle/product/11.2.0/db_1/network/admin) ) ) ENCRYPTION_WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY= /u01/app/oracle/admin/dave/wallet) ) ) SQLNET.WALLET_OVERRIDE = TRUE SSL_CLIENT_AUTHENTICATION = FALSE SSL_VERSION = 0 --添加完之后,重启listener,使参数生效。 --创建wallet:包括设置密码、生成信任文件、并启动wallet CONN / AS SYSDBA -- 10g version ALTER SYSTEM SET ENCRYPTIONKEYAUTHENTICATED BY "myPassword"; -- 11g version ALTER SYSTEM SET ENCRYPTIONKEYIDENTIFIED BY "myPassword"; 当实例重启后或者wallet被关闭后,必须重新open wallets,这样才能保护被加密的列. 而在Openwallet之前,数据库必须处于mount 状态。 SQL>STARTUP MOUNT; SQL> ALTERSYSTEM SET ENCRYPTION WALLET OPEN IDENTIFIED BY "myPassword"; SQL>ALTER DATABASE OPEN; -- 10g version ALTER SYSTEM SET ENCRYPTION WALLET OPEN AUTHENTICATEDBY "myPassword"; -- 11g version ALTER SYSTEM SET ENCRYPTION WALLET OPEN IDENTIFIEDBY "myPassword"; --关闭Wallet: ALTER SYSTEM SET ENCRYPTIONWALLET CLOSE IDENTIFIED BY "myPassword"; --使用SQL 创建的wallet 的问题是不能自动登陆,这样我们在关闭wallet或者重启实例后, 都需要手动的来open wallet。 这样有点麻烦,Oracle 提供了wallet 自动登陆功能,可以在创建wallet指定该属性, 也可以在创建后使用owm(Oracle wallet manager)来修改。 --也可使用orapki,显示 orapki wallet display -wallet /u01/app/oracle/admin/dave/encryption_wallet --修改密码 orapki wallet change_pwd -wallet wallet_location[-oldpwd password ] [-newpwd password] --创建自动登录 orapki wallet create -wallet wallet_location -auto_login_only 相关试图: V$ENCRYPTION_WALLET v$wallet dba_encrypted_columns
参考
- https://docs.oracle.com/cd/E11882_01/network.112/e40393/asotrans.htm#ASOAG10143
- http://www.xifenfei.com/2016/01/oracle-tde-%E7%AE%80%E5%8D%95%E6%B5%8B%E8%AF%95.html
- https://www.oracle.com/technetwork/database/security/twp-transparent-data-encrypa
- https://docs.oracle.com/cd/E11882_01/network.112/e36292/data_encryption.htm#DBSEG80087