数据泄露事件频发的今天,只依赖操作系统权限和数据库账号保护数据已经不够了。攻击者只要拿到数据文件、备份集或者直接拷贝磁盘,就可能用工具绕过数据库直接读取裸数据。Oracle的透明数据加密(Transparent Data Encryption,简称TDE)就是为了解决这个问题的:数据在写入磁盘前被自动加密,读取时自动解密,整个过程对应用和普通SQL完全透明。本文将完整讲解TDE的实施步骤,从钱包创建到表空间加密落地,帮你避开常见的坑。

一、TDE的核心概念:先搞懂Keystore和主密钥
很多DBA上手就敲命令,结果概念混乱导致后期运维困难。TDE体系里有两个关键角色需要先分清楚。第一个是Keystore(早期版本叫Wallet,钱包),它是一个加密文件,用来存放主加密密钥。第二个是Master Key(主密钥),它才是真正用来加密表空间密钥或列加密密钥的根密钥。也就是说,数据并不是被主密钥直接加密的,而是分层加密:主密钥保护数据密钥,数据密钥再保护业务数据。
这种分层设计的好处显而易见。当需要更换主密钥时(比如安全审计要求定期轮换),只需要重新加密那些数据密钥,而不用把几百GB的表空间数据全部重写一遍,轮换操作可以在秒级完成。
Keystore有软件钱包和硬件安全模块(HSM)两种形态。软件钱包就是一个操作系统层面的文件,通常位于$ORACLE_BASE/admin/$ORACLE_SID/wallet目录下,文件名为ewallet.p12。生产环境如果安全等级要求高,建议使用HSM或者带自动登录特性的OKV等方案,但绝大多数企业第一步实施的还是软件钱包,本文也以此为主线展开。
二、实施前的环境准备和参数配置
实施TDE之前,先确认数据库版本。Oracle 12c之后推荐使用统一的ADMINISTER KEY MANAGEMENT语法,11g时代的老语法ALTER SYSTEM SET ENCRYPTION KEY在新版本中虽然还兼容,但不再建议使用。下面以12c及以上版本为例演示。
第一步是配置钱包目录参数。在参数文件中设置:
SQL> show parameter wallet_root; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ wallet_root string /u01/app/oracle/admin/orcl/wallet SQL> alter system set wallet_root='/u01/app/oracle/admin/orcl/wallet' scope=spfile; System altered.
多租户环境下,如果是CDB级别统一管理钱包,只设置WALLET_ROOT即可;如果各PDB需要独立钱包,还要配合TDE_CONFIGURATION参数指定KEYSTORE_CONFIGURATION=FILE。单实例非CDB数据库则相对简单,设置好目录重启生效就行。
第二步检查目录权限。钱包文件必须只有oracle用户可读写,权限设置为700或更严格。目录权限过松是常见的安全隐患,等于把保险柜钥匙挂在了门上。
三、创建Keystore并设置主密钥
目录准备好后,登录数据库创建密码型Keystore。注意必须以SYSDBA或拥有SYSKM权限的用户执行:
-- 创建密码型keystore SQL> administer key management 2 create keystore '/u01/app/oracle/admin/orcl/wallet' 3 identified by "Wallet#Pass2024"; keystore altered. -- 打开keystore SQL> administer key management 2 set keystore open 3 identified by "Wallet#Pass2024"; keystore altered.
接着设置主密钥。单实例直接执行:
SQL> administer key management 2 set key 3 identified by "Wallet#Pass2024" 4 with backup; keystore altered.
with backup子句会在设置主密钥前自动备份一份旧钱包文件,生产环境务必带上。执行成功后可以查询V$ENCRYPTION_WALLET视图确认状态:
SQL> select wallet_type, status, con_id from v$encryption_wallet; WALLET_TYPE STATUS CON_ID -------------------- ------------------------------ ---------- PASSWORD OPEN 1
状态显示OPEN且类型为PASSWORD,说明Keystore已经可以正常工作了。为了避免每次重启数据库都要手动开钱包,可以再创建一个自动登录Keystore:
SQL> administer key management 2 create auto_login keystore 3 from keystore '/u01/app/oracle/admin/orcl/wallet' 4 identified by "Wallet#Pass2024";
自动登录钱包文件为cwallet.sso,数据库启动时会自动打开。需要注意的是,自动登录文件拷贝到别的机器也能用,安全性略低于纯密码钱包,安全要求极高的系统要权衡使用。
四、加密表空间的完整步骤
从Oracle 11.2.11开始就支持加密表空间,这也是目前最推荐的TDE实施方式,因为它对所有数据类型生效,且不需要改任何应用SQL。加密算法可选AES128、AES192、AES256和3DES168,一般选默认的AES256即可。
新建加密表空间的语法如下:
SQL> create tablespace ts_encrypted 2 datafile '/u01/app/oracle/oradata/orcl/ts_encrypted01.dbf' 3 size 1g autoextend on next 100m 4 encryption using 'AES256' 5 default storage (encrypt); Tablespace created.
验证加密是否生效,可以查看V$ENCRYPTED_TABLESPACES视图:
SQL> select tablespace_name, encrypted from dba_tablespaces; TABLESPACE_NAME ENC ------------------------------ --- TS_ENCRYPTED YES USERS NO
对于已存在大量数据的表空间,不能原地修改为加密,需要通过几种方式迁移:第一种是ALTER TABLE ... MOVE ONLINE把表搬到加密表空间,12.2以上支持在线移动不影响业务;第二种是数据泵导出后重新导入到加密表空间;第三种是使用DBMS_REDEFINITION在线重定义。数据量大的系统建议分批迁移,避开业务高峰。
另外还有一种精细化的列加密方式,适合只需要保护个别字段(如身份证号、银行卡号)的场景:
SQL> create table customer_info ( 2 id number primary key, 3 name varchar2(50), 4 id_card varchar2(18) encrypt using 'AES256' 5 ); Table created.
列加密的优势是粒度细,只加密敏感字段,性能开销最小;缺点是索引功能受限,加密列上的等值查询可以走索引,但范围扫描和LIKE模糊匹配效率会受影响。表空间加密则整体开销更均匀,一般生产环境吞吐量影响在个位数百分比,多数业务可以接受。
五、实施后的运维要点和常见坑
TDE上线不是终点,钱包管理才是长期考验。最重要的一条:钱包文件必须随数据库备份一起妥善保存。如果数据文件备份还在,但钱包和主密钥丢了,加密数据将永久无法解密,这种情况没有任何补救手段。建议把钱包备份纳入RMAN备份策略,并且异地存放。
钱包密码的保管同样关键。密码型Keystore的密码只有DBA团队中极少数人应该知道,密码丢失后虽然可以用自动登录钱包重建,但如果两个文件都没了就只能靠平时的备份了。定期轮换主密钥的命令如下:
SQL> administer key management 2 set key identified by "Wallet#Pass2024" 3 with backup using 'key_rotate_20240601';
RAC环境下要注意钱包目录必须放在共享存储上,所有节点都能访问同一份ewallet.p12,否则会出现部分实例钱包打不开导致业务报错的情况。Data Guard环境则要求主库和备库使用相同的Keystore,备库端需要同步钱包文件并保证密码一致。
最后说说性能评估。加密开销主要发生在CPU层面,AES-NI指令集的现代CPU上开销很小。上线前建议用AWR对比典型业务的逻辑读和CPU使用率,重点关注加密表空间上的大范围索引扫描和高并发DML场景。经验上,OLTP系统基本无感,大量全表扫描的报表类系统可能需要多预留百分之五到百分之十的CPU余量。只要规划到位,TDE可以做到业务零改造的前提下显著提升数据安全水位,是性价比很高的防护手段。
Oracle TDE透明数据加密表空间加密修改时间:2026-09-12 13:00:48