Oracle Database 12c Security - 11. Oracle Transparent Data Encryption

Transparent Data Encryption以下简称TDE。

称为透明是因为加密工作在SQL层以下,由数据库引擎自动进行。

TDE是第三代加密,10gR2时引入。之前两代为DBMS_OBFUSCATION_TOOLKIT和DBMS_CRYPTO。

TDE最大的好处是不用改应用。

ENCRYPTION 101

cryptography - 密码学

Goal of Encryption

加密的目的是保护在不安全媒介上传输的敏感信息。

数据库安全与网络安全很不同。不过在透明上是相同的,即网络使用SSL和TLS。

The Basics

加密将明文转换为不可辨识的形式。解密反之。研究此两过程称为密码学。
参考书籍《Applied Cryptography: Protocols, Algorithms, and Source Code in C》

Encryption Choices

自己写加解密算法是不明智的,应选择标准的,经验证的算法。

The Algorithm and the Key

加密数据需要算法和加密key,加密的强调取决于两者组合。算法使用加密key加密数据。

由于算法是公开的,因此唯一需要保密的是加密key。

两类加密算法:对称和非对称(PKE或Public Key Encryption)。 对称算法包括DES,3DES,AES,TLS等,由于效率高,通常用于加密大批量数据。TLS是网络加密的标准。

PKE中的两个key称为公钥和私钥。私钥加密的数据可以用公钥解密,反之亦然。PKE解决了密钥发布的问题。

私钥也解决了认证的问题。

在对称加密中,PKE可用来加密加密key。

为效率计,数据库加密也使用对称加密,不够需要解决密钥管理的问题。

ENCRYPTING DATA STORED IN THE DATABASE

加密的第一需求来自合规性,如PCI DSS。第二需求来自生命周期管理,如备份,复制等。

防止DBA看到敏感数据需要DBV。

Where the Data “Rests”

在TDE之前,磁盘上的数据是明码存放。

Protecting the Data

如果有OS权限,以下命令可以看到明码数据:

strings *.dbf | grep pattern

Applied Example

更换磁盘是必须完全擦除数据,如shred。

Encrypting in the Database

文件系统加密是blanket approach(整体的方法),即加密所有,但比较昂贵(耗资源)。

应用加密如DBMS_CRYPTO则需要改应用。

THE TRANSPARENT DATA ENCRYPTION SOLUTION

TDE是声明式的,支持所有原生数据库功能。

TDE直接,简单。

Key Management Facilities

以下数据加密key称为DEK,加密DEK的密钥称为MEK(master key或master encryption key)。

在12c中,所有PDB共享一个key store,但每一个PDB可以有自己的MEK和DEK。

实际上,在19c中,PDB可以指定自己的key store,这成为isolated mode,而传统的方式称为united mode, 详见https://docs.oracle.com/en/database/oracle/oracle-database/19/asoag/managing-keystores-encryption-keys-in-isolated-mode.html#GUID-1637E45A-36BA-4BC8-B9E3-581515A9AA1C。
本文只讨论unitied mode。

MEK存放在keystore中,有3种保护方法:

  1. 口令保护:使用口令打开key store
  2. 自动登录:自动生成口令并自动打开keystore
  3. 本地自动登录

TDE可以于HSM(hardware security modules)结合。

在创建key store前,必须先建立wallet目录,如果是RAC建议创建在共享的ASM中:

$ mkdir $ORACLE_BASE/admin/ORCLCDB/wallet

然后指定wallet目录,编辑文件$ORACLE_HOME/network/admin/sqlnet.ora

ENRYPTION_WALLET_LOCATION =(SOURCE=(METHOD=file) (METHOD_DATA=(DIRECTORY=/opt/oracle/admin/ORCLCDB/wallet)))

最后重启数据库。

Key Management Roles

12c中有专门的SYSKM权限,PDB中可使用ADMINISTER KEY MANAGEMENT权限。

connect / as sysdba

alter session set container=sales;

grant create session to sec_mgr identified by welcome1;

create role sec_mgr_role;

GRANT administer key management TO sec_mgr_role;

GRANT SELECT ON gv_$encryption_wallet TO sec_mgr_role;
GRANT SELECT ON gv_$encryption_keys TO sec_mgr_role;
GRANT SELECT ON gv_$encrypted_tablespaces TO sec_mgr_role;

grant sec_mgr_role to sec_mgr;

Creating Keystores and a Master Key in the Root Container

首先要在CDB中设置:

connect / as syskm

-- 口令保护的key store
ADMINISTER KEY MANAGEMENT
CREATE KEYSTORE '/opt/oracle/admin/ORCLCDB/wallet'
IDENTIFIED BY welcome1;

然后在目录下可看到新文件,p12后缀是因其遵循PKCS #12标准:

$ ll /opt/oracle/admin/ORCLCDB/wallet
total 4
-rw-------. 1 oracle oinstall 2555 Aug 26 23:13 ewallet.p12

以下命令创建自动登录的key store,也就是不需要口令,这是不安全的,生产环境不建议使用:

ADMINISTER KEY MANAGEMENT
CREATE LOCAL AUTO_LOGIN KEYSTORE
FROM KEYSTORE '/opt/oracle/admin/ORCLCDB/wallet'
IDENTIFIED BY welcome1;

我们可以看到多了sso文件:

$ ll /opt/oracle/admin/ORCLCDB/wallet
total 8
-rw-------. 1 oracle oinstall 2600 Aug 26 23:17 cwallet.sso
-rw-------. 1 oracle oinstall 2555 Aug 26 23:13 ewallet.p12

目前的状态是:

column wrl_parameter format a35
column wallet_type format a20
column status format a19
SELECT wrl_parameter, wallet_type, status
FROM sys.gv_$encryption_wallet;

WRL_PARAMETER                       WALLET_TYPE          STATUS
----------------------------------- -------------------- -------------------
/opt/oracle/admin/ORCLCDB/wallet    LOCAL_AUTOLOGIN      OPEN_NO_MASTER_KEY

在PDB中查询结果:

WRL_PARAMETER                       WALLET_TYPE          STATUS
----------------------------------- -------------------- -------------------
                                    LOCAL_AUTOLOGIN      OPEN_NO_MASTER_KEY

escrow - 代管,托管。

注意, Keystore一旦创建就不应该删除,因此也没有删除命令

如何将自动登录的key store更改为口令保护的key store? 可参考How to convert Local Autologin/Autologin Keystore to Password based Keystore (Doc ID 2061244.1):

SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE;

keystore altered.

SQL> SELECT wrl_parameter, wallet_type, status FROM sys.gv_$encryption_wallet;

WRL_PARAMETER                       WALLET_TYPE          STATUS
----------------------------------- -------------------- -------------------
/opt/oracle/admin/ORCLCDB/wallet    UNKNOWN              CLOSED
                                    UNKNOWN              CLOSED
                                    UNKNOWN              CLOSED
                                    UNKNOWN              CLOSED

SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY welcome1;

keystore altered.

SQL> SELECT wrl_parameter, wallet_type, status FROM sys.gv_$encryption_wallet;

WRL_PARAMETER                       WALLET_TYPE          STATUS
----------------------------------- -------------------- -------------------
/opt/oracle/admin/ORCLCDB/wallet    PASSWORD             OPEN_NO_MASTER_KEY
                                    UNKNOWN              CLOSED
                                    UNKNOWN              CLOSED
                                    UNKNOWN              CLOSED

好了,现在可以用以下命令来打开和关闭key store:

ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE IDENTIFIED BY welcome1 CONTAINER = ALL;

ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY welcome1 CONTAINER = ALL;

下面开始创建MEK。首先必须设置CDB中的MEK, 否则直接在PDB中创建会报错:

SQL> administer key management use key 'AcR7hDRNxk/fv05JQML4YLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' identified by "welcome1" with backup;
administer key management use key 'AcR7hDRNxk/fv05JQML4YLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' identified by "welcome1" with backup
*
ERROR at line 1:
ORA-46671: master key not set in root container

CDB中的过程如下:

connect / as sysdba

ADMINISTER KEY MANAGEMENT
CREATE KEY
USING TAG 'root'
IDENTIFIED BY welcome1
WITH BACKUP
;

SQL> SELECT tag,key_id FROM v$encryption_keys;

TAG        KEY_ID
---------- ------------------------------------------------------------------------------
root       AQKj4ziKK0/3vz9xxCSOOxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

administer key management use key 'AQKj4ziKK0/3vz9xxCSOOxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' identified by "welcome1" with backup;

以上的CREATE和USE可以直接用SET一步替代:

administer key management set key identified by "welcome1" with backup;

此时, CDB和PDB$SEED的key stor状态为OPEN, 表示其中有MEK了:

SQL> SELECT con_id, wrl_parameter, wallet_type, status FROM sys.gv_$encryption_wallet;

    CON_ID WRL_PARAMETER                       WALLET_TYPE          STATUS
---------- ----------------------------------- -------------------- -------------------
         1 /opt/oracle/admin/ORCLCDB/wallet    PASSWORD             OPEN
         2                                     PASSWORD             OPEN
         3                                     PASSWORD             OPEN_NO_MASTER_KEY
         4                                     PASSWORD             OPEN_NO_MASTER_KEY

Creating Master Keys in Pluggable Databases

接下来在某PDB中创建2个MEK:

alter session set container=sales;

ADMINISTER KEY MANAGEMENT
CREATE KEY
USING TAG 'sales1'
IDENTIFIED BY welcome1
WITH BACKUP USING 'root_create'
;

ADMINISTER KEY MANAGEMENT
CREATE KEY
USING TAG 'sales2'
IDENTIFIED BY welcome1
WITH BACKUP USING 'sales_create'
;

SELECT tag,creator,key_use
,to_char(creation_time,'DD-MON-YYYY HH24:MI:SS') creation_time
   FROM sys.gv_$encryption_keys;

TAG        CREATOR    KEY_USE    CREATION_TIME
---------- ---------- ---------- -----------------------------
sales1     SYS        TDE IN PDB 27-AUG-2020 02:58:27
sales2     SYS        TDE IN PDB 27-AUG-2020 03:06:27
root       SYS        TDE IN PDB 27-AUG-2020 03:29:15

以上语句中的WITH BACKUP会备份key store。

我们在pdb中创建了两个MEK,现在需要激活一个:

SQL> SELECT tag,key_id FROM v$encryption_keys;

TAG        KEY_ID
---------- ------------------------------------------------------------------------------
root       AQKj4ziKK0/3vz9xxCSOOxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
sales      AcR7hDRNxk/fv05JQML4YLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
root       AZbgQL5oLU80vwZ6ZxGzp0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

SQL> SELECT wrl_parameter, wallet_type, status FROM sys.gv_$encryption_wallet;

WRL_PARAMETER                       WALLET_TYPE          STATUS
----------------------------------- -------------------- -------------------
                                    PASSWORD             OPEN_NO_MASTER_KEY

SQL> administer key management use key 'AcR7hDRNxk/fv05JQML4YLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' identified by "welcome1" with backup;

keystore altered.

SQL> SELECT wrl_parameter, wallet_type, status FROM sys.gv_$encryption_wallet;

WRL_PARAMETER                       WALLET_TYPE          STATUS
----------------------------------- -------------------- -------------------
                                    PASSWORD             OPEN

administer key management use key 'AcR7hDRNxk/fv05JQML4YLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' identified by "welcome1" with backup;

通过con_id, 我们可以知道每个PDB使用的MEK:

SQL> SELECT con_id, key_id FROM v$encryption_keys;

    CON_ID KEY_ID
---------- ------------------------------------------------------------------------------
         1 AQKj4ziKK0/3vz9xxCSOOxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
         4 AcR7hDRNxk/fv05JQML4YLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
         0 AZbgQL5oLU80vwZ6ZxGzp0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

也可以通过最近激活时间来判断:

SQL> show con_id

CON_ID
------------------------------
4
SELECT KEY_ID
FROM V$ENCRYPTION_KEYS
WHERE ACTIVATION_TIME = (SELECT MAX(ACTIVATION_TIME)
                         FROM V$ENCRYPTION_KEYS
  5                           WHERE ACTIVATING_DBID = (SELECT DBID FROM V$DATABASE));

KEY_ID
------------------------------------------------------------------------------
AcR7hDRNxk/fv05JQML4YLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

由于所有PDB共享key store,而MEK存于key store,因此你创建的MEK可以为所有PDB使用。

Creating an Encrypted Column in a New Table

列加密的最简形式:

create table foo(a int, b varchar(2) encrypt);

复杂一点的:

create table bar(a int, b varchar(2) encrypt using 'AES192' 'SHA-1' SALT);

其中AES192为加密算法。SHA-1为MAC(message authentication code)算法,需要额外的20字节。SALT会在数据后附加16随机字节,这样相同的数据可加密结果不同。

Determining TDE Encrypted Columns

COL OWNER format a10
COL TABLE_NAME format a15
COL COLUMN_NAME format a15
COL ENCRYPTION_ALG format a18
COL SALT format a5
SELECT owner, table_name, column_name
, encryption_alg, salt
    FROM dba_encrypted_columns;

OWNER      TABLE_NAME      COLUMN_NAME     ENCRYPTION_ALG     SALT
---------- --------------- --------------- ------------------ -----
HR         FOO             B               AES 192 bits key   YES

每个表使用不同的DEK,而且是对称key。然后DEK使用MEK加密,这种两级方式使得MEK的rekey非常简单。

Encrypting an Existing Column

已有表的加密:

create table foo(a int, b varchar(2));
alter table foo modify (b encrypt);

由于加密会增加字节,可能会导致性能问题。因此建议对表做reorg。

手工的方法是通过impdp和expdp做导出导入。

自动的方法是通过online redefinition。可参考这里

Caveats to Column-Level TDE

列加密工作在SQL层:

TDE column encryption is performed at the SQL layer. Oracle Database utilities that bypass the SQL layer cannot use TDE column encryption services.

列加密的限制参见Restrictions on Using TDE Column Encryption

推荐表空间加密,它没有任何限制。

Tablespace Encryption

CREATE TABLESPACE sales_encrypt
DATAFILE 'sales_encrypt.dbf' SIZE 50M
ENCRYPTION USING 'AES256'
DEFAULT STORAGE (ENCRYPT);

Tablespace created.

SELECT ts.name, et.encryptedts, et.encryptionalg
FROM v$tablespace ts, v$encrypted_tablespaces et
WHERE ts.ts# = et.ts#;

NAME                           ENC ENCRYPT
------------------------------ --- -------
SALES_ENCRYPT                  YES AES256

然后可以将已有的表迁移到加密表空间:

SQL> create table t1(a int);

Table created.

SQL> alter table t1 move tablespace sales_encrypt;

Table altered.

加密已有的表空间:

SQL> CREATE TABLESPACE noencrypt datafile 'noencrypt.dbf' size 10M;

Tablespace created.

SQL> ALTER TABLESPACE noencrypt ENCRYPTION ONLINE USING 'AES192' ENCRYPT;

Tablespace altered.

可参考这里

TDE AND ORACLE DATABASE TOOLS INTEROPERABILITY

当数据需要移动时,TDE需要和其它工具配合使用,如OGG,Data Pump, ADG,详见Oracle Database Advanced Security Guide。

PERFORMANCE

性能视情况而定,总之建议用表空间加密。如果用列加密,需要注意不要用在逐渐,主外键约束等。

另外可考虑硬件加速,参见:How To Benefit From Hardware Acceleration for Tablespace Encryption? (Doc ID 1365021.1)。

ADVANCED ENCRYPTION PROTECTION SUPPORT

Oracle数据库支持FIPS 140-2,设置参见How To Setup Federal Information Processing Standard (FIPS) standard for 140-2 Using FIPS.ORA On Single Instance and On RAC ( Real Application Cluster) (Doc ID 2250070.1)。

SQL> show parameter fips;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
DBFIPS_140                           boolean     FALSE

可用于网络数据,静态数据的加密,以及DBMS_CRYPTO package。

参考

  • Master Note For Transparent Data Encryption ( TDE ) (Doc ID 1228046.1)
  • TDE 12c : Frequently Asked Questions (Doc ID 2253348.1)
  • Master Note: Overview of Oracle Tablespace Management (Doc ID 1493350.1)
  • All About Security: User, Privilege, Role, SYSDBA, O/S Authentication, Audit, Encryption, OLS, Database Vault, Audit Vault (Doc ID 207959.1)
  • Oracle TDE: How to Use It and Survive
  • Getting Started With Transparent Data Encryption in Oracle 12c (non pluggable database ) (Doc ID 1964158.1)

你可能感兴趣的:(Oracle,12c,Oracle数据库安全)