Oracle Korea Magazine 2009년 겨울호가 발간되었네요.


Cover Story
더욱 강력해진 Oracle Database 11g Release2를 경험하라
· 더욱 강력해진 Oracle Database 11g Release2를 경험하라
· 제주대학교병원, Oracle Database 11g 기반의 안정성과 고가용성 갖춘 통합의료정보시스템 운영
· 릴리즈는 숫자 하나의 ‘차이’, 그러나 …

Trend
· 세계를 사로잡은 Oracle Siebel CRM Solution 저자 -
· 개인정보 보호가 최대 이슈, 오라클만의 보안 솔루션
· 기업 정보유통구조의 혁신과 엔터프라이즈 2.0

Technology & Developer
· SOA 환경의 데이터 서비스 : 기업은, 넓고 수평적인 시각의 SOA 환경을 원한다
· SOA Data On Coherence : 기업 업무 데이터 손실 예방을 위한 Grid Solution과의 결합 저자 -
· DBMS_ROWID에서의 파싱 및 사이징
· 오라클 대용량 데이터베이스 성능 튜닝

About Oracle
· 위대한 변화를 꿈꾸고 있는 오라클
    Oracle Open World 2009 참관기
· 세계 최고의 성능과 속도를 자랑하는 Sun Oracle Database Machine
    Oracle Exadata V2 발표
· “새 시대를 여는 차세대 IT 시스템을 제공하겠습니다.”
    오라클 President, 찰스 필립스와 함께하는 Oracle Executive Dinner 개최
· 아시아태평양 지역 올해의 CIO 수상
    STX 그룹 CIO, 김효중 사장
· 신속한 답변을 원하십니까?
    OracleDirect가 고객 여러분과 항상 함께 하겠습니다





Oracle Korea Magazine

Oracle Magazine
Summer 2009

PDF 차세대 애플리케이션
인프라의 비전을 제시하다
Oracle Application Grid
  지난호 보기







2009년 1월 오라클 매거진에 실린 tablespace encrypting에 관한 설명입니다.
이전의 column encrypting의 제한을 없앴다고하네요..

전 써보진 않았지만.. 유용할 듯..


Encrypting Tablespaces
By Arup Nanda Oracle ACE

Encrypt tablespaces transparently—without affecting performance.

In an era when data security is critical in almost every type of business, databases are particularly important. This is where the organization’s crown jewels live—credit card numbers, Social Security information, names and addresses—the list is endless. The data security risk increases when business data leaves the security of an organization’s databases in the form of backup tapes. Historically, these offsite tapes have been the source of many data thefts. And because the tapes can be restored on any equivalent machine, attackers can browse the data at their leisure, and there is nothing the organization can do to protect the data then.

How can you prevent this from happening? The simple answer is encryption—encrypt the data in the database and store the encryption key in a different place. Thieves might be able to access the backup tapes and restore the database on a different server, but without the encryption key, they won’t be able to see the data.

Oracle introduced transparent data encryption (TDE) column encryption in Oracle Advanced Security with the release of Oracle Database 10g Release 2. (For more information, see “Transparent Data Encryption” in the September/October 2005 issue of Oracle Magazine.) Although this feature enables you to encrypt columns of a table without writing a single piece of code and helps with several key compliance regulations, it can negatively affect performance in applications when an encrypted column is used in range scans or as a foreign key. Column encryption is performed transparently within the database SQL layer, and indexes on an encrypted column are built on the encrypted values. Because encrypted values look random and disconnected, range scan operations on encrypted columns are not effective. Although column encryption occurs quickly, the range scan limitation is a real challenge in many real-world situations.

Enter TDE Encrypted Tablespaces

The Oracle Advanced Security option for Oracle Database 11g introduces a nifty new TDE feature—tablespace encryption—that allows a whole tablespace to be encrypted and therefore addresses the range scan and foreign key limitation of column-level encryption. The new tablespace is created as encrypted, and the data, whether tables or indexes, is stored encrypted in that tablespace, as shown in Figure 1. When a user selects that data, the server process moves the data from storage to the buffer cache and subsequently to the user’s session. The data is decrypted before being loaded into the buffer cache, so it’s always in cleartext (unencrypted) inside the buffer cache. Almost all types of data access—including index scans, table joins, and so on—happen in the buffer cache, so the performance of operations involving data from the encrypted tablespace is no different from that involving data from a normal, unencrypted tablespace.

Encryption requires at least two things: an encryption key and an algorithm. TDE uses what is known as a two-tier key architecture: both column and tablespace encryption keys are stored in the database but are encrypted with another key called the master key. The master key is stored outside the database in a special container called an external security module, which can be something as easy to set up as an Oracle wallet or as sophisticated as a hardware security module device. The Oracle wallet is a file formatted according to Public Key Cryptography Standard No. 12 and encrypted with a password. For using the wallet as the external security module, a password must be provided to make the master key accessible to the database. Unless the right password is supplied, the wallet can’t be opened and the encrypted data can’t be retrieved. The wallet is automatically closed when the database instance is shut down and must be reopened by a security officer when the instance starts. So although thieves might be able to restore a database from tapes, without the wallet and the password, they will not be able to view the encrypted data. (In the hardware security module case, the hardware device must be made available to the database in a manner specified by the vendor of the device.)

figure 1
Figure 1: Loading of data buffers

With tablespace encryption, before data buffers are written back to disk (as a result of the checkpoint process), they are encrypted by DB Writer processes (DBWn), as shown in Figure 2. Operations, such as direct path inserts and reads that manipulate the data directly in the database, perform encryption inline. When the log buffers are written to the redo logs by the log writer process, they are encrypted as well, so the initial and subsequently archived redo logs contain only encrypted data.

figure 2
Figure 2: Flushing of buffers from cache to disk

Tablespace Encryption Setup

Let’s look at how to set up TDE tablespace encryption, using a file-based wallet. Note that the compatibility of the database must be set to 11.1 or higher. First, if you don’t have one, create the wallet:

1. Make sure the ORACLE_BASE variable has been set. If it has not, set it by issuing

$ export ORACLE_BASE=/opt/oracle

2.
Change to the ORACLE_BASE directory and then to the admin subdirectory for that instance. In my case, the instance is named prolin1, so I issue

$ cd $ORACLE_BASE/admin/prolin1

3.
Create a directory called “wallet” to hold the wallet:

$ mkdir wallet

4.
Create the wallet, along with a secure password, preferably containing a mix of alphanumeric characters, such as “T45rustMe54”:

$ sqlplus / as sysdba

SQL> alter system set encryption key

identified by "T45rustMe54";

The password is case-sensitive.

The preceding step will create the wallet as well as open it. You need to create the wallet only once. After the database is opened, the wallet remains open until either the wallet is explicitly closed or the database is shut down, at which time the wallet automatically closes. You can reopen this wallet after the database is restarted, by using

SQL> alter system set wallet open 


identified by "T45rustMe54";



System altered.



Now that the wallet is set up, you can create the encrypted tablespace.

1. The following code sets up an encrypted tablespace named enc128_ts:

 



create tablespace enc128_ts



datafile '/u01/oracle/database/



enc128_ts.dbf'



size 1M autoextend on next 1M



encryption using 'AES128'



default storage (encrypt)



/



Note the special encryption using 'AES128’ clause, which indicates that the AES algorithm is to be used with a 128-bit key. You can also use the values AES192 and AES256 (in place of AES128, the default value) to use 192- and 256-bit keys, respectively.

2. Once the tablespace is created, you can create objects in it. For instance, the following code creates a table called ACCOUNTS_ENC:

create table accounts_enc (



ACC_NO NUMBER NOT NULL,



FIRST_NAME VARCHAR2(30) NOT NULL,



... other columns ...



)



tablespace enc128_ts;



That’s it; no special clause is required. All the columns of the table (or anything else created in this tablespace) will be encrypted.

To confirm encryption, you can insert a record with a value “David” for FIRST_NAME and search the datafile you created for the enc128_ts tablespace for that value:

 



SQL> insert into accounts_enc values (1, 'David' , ...);



$ strings enc128ts_ts.dbf | grep David



This will not show any output, because the “David” value has been stored in an encrypted tablespace. Searching for a cleartext value found nothing, as expected. (Note that if you do a string search in a file of an unencrypted tablespace, a successful search will return the cleartext from the file.)

Tablespace Encryption and Performance

An issue with any encryption method is the negative impact on performance. For example, searches for patterns in the values in an encrypted column may or may not be able to use indexes. That is exactly where TDE tablespace encryption excels—it allows data to be in cleartext in the buffer cache, where all the searching occurs.

To accurately ascertain the performance impact of encryption in the tablespace, we can do a small test. First, let’s create one normal tablespace:

create tablespace normal_ts



datafile '/u01/oracle/database/



normal_ts.dbf'



size 1M autoextend on next 1M;



Next, let’s create two identical tables—ACCOUNTS_REG and ACCOUNTS_ENC—in tablespaces normal_ts and enc128_ts (the encrypted tablespace we created earlier), respectively, and populate the tables in the same way. Finally, let’s create an index on each of the tables on the FIRST_NAME column. The code for creating the tables and populating the data is available in the sample code download for this article.

With the data set up, we run a query against one table, ACCOUNTS_REG, to find all the first names starting with D. This query uses an index on the FIRST_NAME column, as shown in Listing 1. Next, we run the same query but replace ACCOUNTS_REG with ACCOUNTS_ENC, as shown in Listing 2. The execution time is approximately the same for the query in both the unencrypted and encrypted tablespaces, with about the same number of blocks fetched in both cases. This shows that there is no significant performance penalty for querying tables in encrypted tablespaces.

Code Listing 1: Index scan on table in unencrypted tablespace

SQL> set autot on explain stat



SQL> set timing on



SQL> select first_name



2 from accounts_reg



3 where first_name like 'D%'



4 /







... the rows come here ...







50161 rows selected.







Elapsed: 00:05:36.38







Execution Plan



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



Plan hash value: 966430551







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



| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |



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



| 0 | SELECT STATEMENT | | 210K| 1442K| 513 (1)| 00:00:07 |



|* 1 | INDEX RANGE SCAN|IN_ACC_REG_FN | 210K| 1442K| 513 (1)| 00:00:07 |



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



Predicate Information (identified by operation id):



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







1 - access("FIRST_NAME" LIKE 'D%')



filter("FIRST_NAME" LIKE 'D%')











Statistics



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



1 recursive calls



0 db block gets



3458 consistent gets



127 physical reads



...



Code Listing 2: Index scan on table in encrypted tablespace

SQL> set autot on explain stat



SQL> set timing on



SQL> select first_name



2 from accounts_enc



3 where first_name like 'D%'



4 /







... the rows come here ...







Elapsed: 00:05:33.85







Execution Plan



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



Plan hash value: 399953395







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



| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |



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



| 0 | SELECT STATEMENT | | 210K| 1442K| 513 (1)| 00:00:07 |



|* 1 | INDEX RANGE SCAN | IN_ACC_ENC_FN | 210K| 1442K| 513 (1)| 00:00:07 |



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







Predicate Information (identified by operation id):



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







1 - access("FIRST_NAME" LIKE 'D%')



filter("FIRST_NAME" LIKE 'D%')











Statistics



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



1 recursive calls



0 db block gets



3427 consistent gets



127 physical reads



...



Comparison of Tablespace and Column-Level Encryption

Column-level TDE allows you to encrypt data in a specific column only. This is how to encrypt the FIRST_NAME column in the ACCOUNTS_REG_ENC table, created from the ACCOUNTS_REG table:

create table accounts_reg_enc 



nologging as



select * from accounts_reg;







alter table accounts_reg_enc



modify first_name encrypt using 'AES128'



no salt;



After this modification, the FIRST_NAME column values will be stored encrypted in the ACCOUNTS_REG_ENC table. All other columns will be in cleartext. However, because the blocks of this table in the buffer cache will be replicas of the table, the FIRST_NAME column will still be encrypted in the buffer cache. So, there will be a severe impact on the performance of the index scans using FIRST_NAME.

Let’s examine the impact by running a small test. We issue a query against the ACCOUNTS_REG_ ENC table (which is in an unencrypted tablespace but with its FIRST_NAME column encrypted). We search for first names starting with D, and the query uses the index. We repeat the query against the ACCOUNTS_ENC table (in the encrypted tablespace). Then we examine the impact of the encrypted column on query performance, by issuing autotrace on explain stat, which shows the optimization plan used as well as statistics such as consistent gets. Listing 3 shows the commands and the output.

Code Listing 3: Query comparison of column-level and tablespace encryption

/* Run a query on the ACCOUNTS_REG_ENC table (in the unencrypted */



/* tablespace, but with the encrypted first_name column): */







SQL> set autotrace on explain stat



SQL> set linesize 120



SQL> select count(1) from accounts_reg_enc



2 where first_name like 'D%';







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



| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |



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



| 0 | SELECT STATEMENT | | 1 | 7 | 686 (5)| 00:00:09 |



| 1 | SORT AGGREGATE | | 1 | 7 | | |



|* 2 | INDEX FAST FULL SCAN| IN_ACC_REG_FN | 50000 | 341K| 686 (5)| 00:00:09 |



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







Predicate Information (identified by operation id):



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







2 - filter(INTERNAL_FUNCTION("FIRST_NAME") LIKE 'D%')











Statistics



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



0 recursive calls



0 db block gets



13963 consistent gets



...







/* Now, run the same query on the ACCOUNTS_ENC table (in the encrypted tablespace): */







SQL> select count(1) from accounts_enc



2 where first_name like 'D%';







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



| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |



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



| 0 | SELECT STATEMENT | | 1 | 7 | 513 (1)| 00:00:07 |



| 1 | SORT AGGREGATE | | 1 | 7 | | |



|* 2 | INDEX RANGE SCAN| IN_ACC_ENC_FN | 210K| 1442K| 513 (1)| 00:00:07 |



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







Predicate Information (identified by operation id):



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







2 - access("FIRST_NAME" LIKE 'D%')



filter("FIRST_NAME" LIKE 'D%')











Statistics



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



0 recursive calls



0 db block gets



120 consistent gets



...



Consider the difference. The access path changed from INDEX FAST FULL SCAN for the table with the encrypted column (ACCOUNTS_REG_ENC) to INDEX RANGE SCAN for the table in the encrypted tablespace (ACCOUNTS_ENC), which resulted in a reduction of consistent gets from 13,963 to a mere 120—less than 1 percent of the original value. This means that the query against the encrypted tablespace table generated just 1 percent of the logical I/O of the query on the table with the encrypted column.

A second major difference is in column restrictions. Certain datatypes can’t be encrypted with TDE column encryption, columns under TDE can’t be used for foreign keys, only B-tree indexes can be created against the columns under TDE—and these are just some of the limitations of TDE column encryption. However, there is no restriction on these objects in an encrypted tablespace.

TDE column encryption has additional space requirements. Typically, encrypted values are larger than unencrypted values, causing a table with column encryption to be larger overall. To check for the exact increase, we can use the show_space procedure to show the space inside the tables—ACCOUNTS_REG (the table in the unencrypted tablespace), ACCOUNTS_ENC (the table in the encrypted tablespace), and ACCOUNTS_REG_ENC (the ACCOUNTS_REG table with only the FIRST_NAME column encrypted). Listing 4 shows the output. Note that the space consumption (of full blocks) is about the same for both forms of the table—in the unencrypted and encrypted tablespaces. However, the table in the unencrypted tablespace with the encrypted column takes about 15K full blocks, against about 10K in the table in the encrypted tablespace—about 50 percent more space. So, not only is the performance better with TDE tablespace encryption, but there is also no discernible additional space consumption, which, in turn, boosts performance by reducing I/O.

Code Listing 4: Space consumption on various forms of the table

SQL> set serveroutput on







SQL> exec show_space ('ACCOUNTS_REG','ARUP')



Unformatted Blocks ..................... 0



FS1 Blocks (0-25) ..................... 2



FS2 Blocks (25-50) ..................... 0



FS3 Blocks (50-75) ..................... 0



FS4 Blocks (75-100)..................... 0



Full Blocks ..................... 10,938



Total Blocks............................ 11,088



Total Bytes............................. 90,832,896



Total MBytes............................ 86



Unused Blocks........................... 1



Unused Bytes............................ 8,192



Last Used Ext FileId.................... 6



Last Used Ext BlockId................... 40,969



Last Used Block......................... 847







SQL> exec show_space ('ACCOUNTS_ENC','ARUP')



Unformatted Blocks ..................... 0



FS1 Blocks (0-25) ..................... 1



FS2 Blocks (25-50) ..................... 0



FS3 Blocks (50-75) ..................... 0



FS4 Blocks (75-100)..................... 1



Full Blocks ..................... 10,967



Total Blocks............................ 11,120



Total Bytes............................. 91,095,040



Total MBytes............................ 86



Unused Blocks........................... 4



Unused Bytes............................ 32,768



Last Used Ext FileId.................... 7



Last Used Ext BlockId................... 10,249



Last Used Block......................... 876











SQL> exec show_space ('ACCOUNTS_REG_ENC','ARUP')



Unformatted Blocks ..................... 0



FS1 Blocks (0-25) ..................... 2



FS2 Blocks (25-50) ..................... 0



FS3 Blocks (50-75) ..................... 0



FS4 Blocks (75-100)..................... 1



Full Blocks ..................... 15,680



Total Blocks............................ 15,856



Total Bytes............................. 129,892,352



Total MBytes............................ 123



Unused Blocks........................... 6



Unused Bytes............................ 49,152



Last Used Ext FileId.................... 6



Last Used Ext BlockId................... 29,705



Last Used Block......................... 490



Encrypted Tablespace Administration

This article has demonstrated how to use the command line to create encrypted tablespaces, but you can also create encrypted tablespaces via Oracle Enterprise Manager. To create an encrypted tablespace in Oracle Enterprise Manager, from the main Database page, choose the Server tab and then click the Tablespaces link under Storage. On the page, click Create, which brings up a screen similar to the one shown in Figure 3. Check the Encryption check box, and click Encryption Options. That will lead to a new screen where you can specify the type of encryption algorithm.

figure 3
Figure 3: Encrypted tablespace creation via Oracle Enterprise Manager

Different database views can help you monitor encrypted tablespaces by indicating the tablespace number, the encryption algorithm, and whether a tablespace is encrypted. The ENCRYPTED column in the DBA_TABLESPACES data dictionary view shows whether a tablespace is encrypted (YES or NO). If a tablespace is encrypted, the relevant information is shown in a different view: V$ENCRYPTED_TABLESPACES.

The V$ENCRYPTED_TABLESPACES view includes the following columns:

  • TS#. The tablespace number
  • ENCRYPTIONALG. The encryption algorithm, such as AES128
  • ENCRYPTEDTS. Indicates whether the tablespace is encrypted (value is YES or NO)

Note that when you recover an encrypted tablespace, the wallet must be open, and you can transport an encrypted tablespace to a different database, but the other database must have the same wallet (and therefore the same master key). The wallet password for the other database can be different, but the wallet must be the same. If you transport an encrypted tablespace across platforms, the target platform must have the same endianness for encrypted tablespaces.

Finally, note that you can only create encrypted tablespaces; you cannot modify existing tablespaces to encrypt them. So, when you need existing data in encrypted tablespaces, the best solution is to first create encrypted tablespaces and then move the objects from the unencrypted tablespaces to them.

Conclusion

In general, encryption solves a security issue while introducing a new one: degraded performance. The latter is not acceptable in many real-world situations, so many organizations have little choice but to sacrifice encryption in favor of performance. With transparent tablespace encryption, however, degraded performance is no longer an issue—the performance in an encrypted tablespace is on a par with cleartext performance in unencrypted tablespaces while the data is protected at the storage level via encryption. And best of all, encryption is done transparently without your having to write a single line of code.

Transparent tablespace encryption is an example of a feature that lets you have your cake and eat it too.




+ Recent posts