客服微信
本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。
Oracle 数据库 12c 引入了一种使用 ADMINISTER KEY MANAGEMENT 命令来管理密钥库、加密密钥和机密的新方法。这取代了以前版本中用于密钥和钱包管理的 ALTER SYSTEM SET ENCRYPTION KEY 和 ALTER SYSTEM SET ENCRYPTION WALLET 命令。文档中的术语自由地混合了术语“钱包”和“密钥库”,但其意图似乎是转向术语“密钥库”,与 Java 术语保持一致。
多租户架构使密钥管理变得有些复杂,因为根容器需要具有活动主加密密钥的开放密钥库。 CDB 密钥库用于存储所有关联 PDB 的加密密钥,但每个 PDB 都需要自己的主加密密钥。 PDB 的主加密密钥必须在拔出操作之前导出,以便可以在后续插入操作之后导入。
本文介绍与透明数据加密 (TDE) 相关的一些基本密钥管理操作。它没有描述所有可能的密钥管理操作,如下所示。
必须创建密钥库来保存加密密钥。查找密钥库的搜索顺序如下。
密钥库不应在 CDB 之间共享,因此如果从同一 ORACLE_HOME 运行多个 CDB,则必须执行以下操作之一以将它们分开。
1、使用默认密钥库位置,因此每个 CDB 数据库都有自己的密钥库。
2、使用 $ORACLE_SID 指定位置
ENCRYPTION_WALLET_LOCATION = (SOURCE =(METHOD = FILE)(METHOD_DATA = (DIRECTORY = /opt/oracle/admin/ORCLCDB/wallet) ) )
3、每个数据库都有一个单独的“sqlnet.ora”,确保 TNS_ADMIN 变量设置正确。
无论您将密钥库放在何处,请确保不会丢失它。
在19C的版本,sqlnet.ora配置是可选的,可以通过以下两个参数来指定密钥位置
alter system set wallet_root='/opt/oracle/admin/ORCLCDB/wallet' scope=spfile; alter system set tde_configuration="keystore_configuration=file" scope=spfile;
编辑“$ORACLE_HOME/network/admin/sqlnet.ora”文件,添加以下条目。
ENCRYPTION_WALLET_LOCATION = (SOURCE =(METHOD = FILE) (METHOD_DATA = (DIRECTORY = /opt/oracle/admin/ORCLCDB/wallet) ) )
创建保存密钥库的目录。
mkdir -p /opt/oracle/admin/ORCLCDB/wallet
conn / as sysdba !mkdir -p /opt/oracle/admin/ORCLCDB/wallet alter system set wallet_root='/opt/oracle/admin/ORCLCDB/wallet' scope=spfile; alter system set keystore_configuration=file scope=spfile; startup force
连接到根容器并创建密钥库。
CONN / AS SYSDBA ADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/opt/oracle/admin/ORCLCDB/wallet' IDENTIFIED BY myPassword; HOST ls /opt/oracle/admin/ORCLCDB/wallet ewallet.p12 SQL>
您可以使用以下命令从根容器打开和关闭密钥库。如果省略 CONTAINER=ALL 子句,则假定为当前容器。打开所有容器的密钥库。
-- Open ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY myPassword CONTAINER=ALL; -- Close ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE IDENTIFIED BY myPassword CONTAINER=ALL;
您需要在根容器中创建并激活一个主密钥,并在每个可插入数据库中创建一个主密钥。使用 CONTAINER=ALL 子句只需一步即可完成此操作。如果省略 CONTAINER=ALL 子句,则只会在当前容器中完成,并且需要单独为每个 PDB 再次完成。有关主密钥的信息使用 V$ENCRYPTION_KEYS 视图显示。
--cdb ADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY myPassword WITH BACKUP CONTAINER=ALL; SET LINESIZE 100 SELECT con_id, key_id FROM v$encryption_keys; CON_ID KEY_ID ---------- ------------------------------------------------------------------------------ 1 AeISFVCP6E/zv1FsutXrjMsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 3 ARgUiSkug0/hvxZq6y0jA9YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA SQL>
有关密钥库的信息使用 V$ENCRYPTION_WALLET 视图显示。
SET LINESIZE 200 COLUMN wrl_parameter FORMAT A50 SELECT * FROM v$encryption_wallet; WRL_TYPE WRL_PARAMETER STATUS WALLET_TYPE WALLET_OR KEYSTORE FULLY_BAC CON_ID -------------------- -------------------------------------------------- ------------------------------ -------------------- --------- -------- --------- ---------- FILE /opt/oracle/admin/ORCLCDB/wallet OPEN PASSWORD SINGLE NONE NO 1 FILE OPEN PASSWORD SINGLE UNITED NO 2 FILE OPEN PASSWORD SINGLE UNITED NO 3
连接到 PDB。如果您未在上一步中创建密钥,请为 PDB 创建新的主密钥。
CONN sys@pdb1 AS SYSDBA -- We don't need to create a master key as we did it previously by using CONTAINER=ALL -- ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY myPassword; -- ADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY myPassword WITH BACKUP; SELECT con_id, key_id FROM v$encryption_keys; CON_ID KEY_ID ---------- ------------------------------------------------------------------------------ 3 AWiGlK8wUE8ivxB0RktczOMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA SQL>
您现在应该能够在 PDB 中创建包含加密列的表。
CONN apps/oracle@pdb1 -- Encrypted column CREATE TABLE tde_test ( id NUMBER(10), data VARCHAR2(50) ENCRYPT ); INSERT INTO tde_test VALUES (1, 'This is a secret!'); COMMIT;
注意:如果加密没有正确设置,在创建表时会报错:ORA-28365: wallet is not open
我们还可以创建加密的表空间。
-- Encrypted tablespacew CONN sys@pdb1 AS SYSDBA CREATE TABLESPACE encrypted_ts DATAFILE SIZE 128K AUTOEXTEND ON NEXT 64K ENCRYPTION USING 'AES256' DEFAULT STORAGE(ENCRYPT); ALTER USER apps QUOTA UNLIMITED ON encrypted_ts; CONN apps/oracle@pdb1 CREATE TABLE tde_ts_test ( id NUMBER(10), data VARCHAR2(50) ) TABLESPACE encrypted_ts; INSERT INTO tde_ts_test VALUES (1, 'This is also a secret!'); COMMIT;
如果重新启动 PDB,则必须先在 PDB 中打开密钥库,然后才能访问数据。
CONN sys@pdb1 AS SYSDBA SHUTDOWN IMMEDIATE; STARTUP; ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY myPassword; CONN apps/oracle@pdb1 SELECT * FROM tde_test; ID DATA ---------- -------------------------------------------------- 1 This is a secret! SQL> SELECT * FROM tde_ts_test; ID DATA ---------- -------------------------------------------------- 1 This is also a secret! SQL>
如果重新启动 CDB,则必须在 CDB 和 PDB 中打开密钥库。
CONN sys@pdb1 AS SYSDBA SHUTDOWN IMMEDIATE; STARTUP; ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY myPassword; CONN apps/oracle@pdb1 SELECT * FROM tde_test; ID DATA ---------- -------------------------------------------------- 1 This is a secret! SQL> SELECT * FROM tde_ts_test; ID DATA ---------- -------------------------------------------------- 1 This is also a secret! SQL>
本节介绍从 CDB1 实例中拔出 PDB1 并以新名称 PDB2 插入同一计算机上的 CDB2 实例的过程。
切换到CDB1实例。
ORAENV_ASK=NO export ORACLE_SID=cdb1 . oraenv ORAENV_ASK=YES sqlplus /nolog
从PDB1导出关键信息。
CONN sys@pdb1 AS SYSDBA ADMINISTER KEY MANAGEMENT EXPORT ENCRYPTION KEYS WITH SECRET "mySecret" TO '/tmp/export.p12' IDENTIFIED BY myPassword;
从 CDB1 上拔下 PDB1。
CONN / AS SYSDBA ALTER PLUGGABLE DATABASE pdb1 CLOSE; ALTER PLUGGABLE DATABASE pdb1 UNPLUG INTO '/tmp/pdb1.xml';
切换到CDB2实例。
ORAENV_ASK=NO export ORACLE_SID=cdb2 . oraenv ORAENV_ASK=YES sqlplus /nolog
将 PDB1 和新名称 PDB2 插入到 CDB2 实例中。
CONN / AS SYSDBA CREATE PLUGGABLE DATABASE pdb2 USING '/tmp/pdb1.xml'; -- If you are not using OMF, you will have to convert the paths manually. --CREATE PLUGGABLE DATABASE pdb2 USING '/tmp/pdb1.xml' -- FILE_NAME_CONVERT=('/u01/app/oracle/oradata/cdb1/pdb1/','/u01/app/oracle/oradata/cdb2/pdb2/'); ALTER PLUGGABLE DATABASE pdb2 OPEN READ WRITE;
打开PDB2会出现如下错误,这一点我们可以忽略。
Warning: PDB altered with errors.
如果 CDB2 在根级别还没有密钥库,您将需要创建它。
CONN / AS SYSDBA HOST mkdir -p /u01/app/oracle/admin/cdb2/encryption_keystore/ ADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/u01/app/oracle/admin/cdb2/encryption_keystore/' IDENTIFIED BY myPassword; ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY myPassword;
将关键信息导入PDB2并重启。在它完全打开之前,它不会向侦听器注册,因此请手动切换容器。
CONN / AS SYSDBA ALTER SESSION SET CONTAINER=pdb2; ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "myPassword"; ADMINISTER KEY MANAGEMENT IMPORT ENCRYPTION KEYS WITH SECRET "mySecret" FROM '/tmp/export.p12' IDENTIFIED BY "myPassword" WITH BACKUP; -- Restart the PDB and open the keystore. SHUTDOWN; STARTUP; ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "myPassword";
加密数据现在可以按预期使用。
CONN test/test@pdb2 SELECT * FROM tde_test; ID DATA ---------- -------------------------------------------------- 1 This is a secret! SQL> SELECT * FROM tde_ts_test; ID DATA ---------- -------------------------------------------------- 1 This is also a secret! SQL>
创建自动登录密钥库意味着您不再需要在重新启动后显式打开密钥库。第一次引用密钥会导致密钥库自动打开,如下所示。
CONN / AS SYSDBA ADMINISTER KEY MANAGEMENT CREATE LOCAL AUTO_LOGIN KEYSTORE FROM KEYSTORE '/opt/oracle/admin/ORCLCDB/wallet' IDENTIFIED BY myPassword; SHUTDOWN IMMEDIATE; STARTUP CONN apps/oracle@pdb1 SELECT * FROM tde_test; ID DATA ---------- -------------------------------------------------- 1 This is a secret! SQL> SELECT * FROM tde_ts_test; ID DATA ---------- -------------------------------------------------- 1 This is also a secret! SQL>
密钥管理可以由 SYSDBA 或 SYSKM 组的任何成员执行。上面的实验是以SYSDBA来配置的,也可以用SYSKM来配置。