2012. 10. 6.

DBMS/오라클] 데이터 암호화 기능



Oracle 8i에서 데이터 암호화 기능 (글 오라클)작성일 : 2003/11/30 21:22
 

  조회수 : 1044

  
 출 처 : 오라클 Technical Bulletins, http://211.106.111.2:8880/bulletin/list.jsp?seq=12036
------------------------------------------------------------------------

No. 12036

데이터 암호화 기능 소개(8.1.6 new feature)
=========================================

개    요
=========
Oracle 8i Release2(8.1.6)에서는 데이터를 암호화하여 저장할 수 있는 향상된
기능(DES Encryption)을 제공한다
(Oracle 8i Release3(8.1.7)에서는 Triple DES Encryption)

즉 신용카드번호, 패스워드 등 보안이 필요한 데이터를 암호화된 형태로 저장하여
기존의 3rd Party Tool이나, Application Logic으로 구현하던 암호화 정책을
데이터베이스 차원에서 구현할 수 있도록 해준다.

DBMS_OBFUSCATION_TOOLKIT
========================
암 호화 기능을 이용하려면 DBMS_OBFUSCATION_TOOLKIT을 이용해야 한다.

이 패키지는 4개의 프로시져로 이루어져 있다.
- VARCHAR2 타입을 Encrypt/Decrypt할 수 있는 2개의 프로시져
- RAW 타입을 Encrypt/Decrypt할 수 있는 2개의 프로시져
(다른 타입은 지원하지 않으므로 number인 경우는 to_char 이용)

DBMS_OBFUSCATION_TOOLKIT을 이용하기 위해서는 :
1) SYS 유저로
   @$ORACLE_HOME/rdbms/admin/dbmsobtk.sql
   @$ORACLE_HOME/rdbms/admin/prvtobtk.plb
2) grant execute on dbms_obfuscation_toolkit to public;


제 한 사 항
===========
1) DES(Data Encryption Standard) symmetric key algorithm 방식을 이용.
   즉 암호화할 때 이용한 key를 분실했을 경우 데이터를 해독할 방법이 없다.

2) Encrypt하려는 data가 8 bytes 배수(8,16,... bytes)이어야 한다.

3) 미국무부의 암호화기술 수출제한조치에 의해 56-bit key를 사용.

4) 미국무부의 암호화기술 수출제한조치에 의해 한번 암호화된 데이터를
   또다시 암호화할 수 없다.

*) 많은 테이블을 Encrypt/decrypt할 경우 CPU 사용량을 증가시킬 수 있다.
*) 아래의 예제는 UTF8을 사용할 경우 한글 데이터를 암호화할 수 없다.
   (RPAD의 제약으로)

사 용 예
========
1) encrypt/decrypt에 이용할 FUNCTION을 만든다.
   (만약 input string이 8 byte 배수가 아니면 패딩을 한다)
*) 8.1.6에서는 key값이 8 byte 이상이어야 함(8.1.7 이후에는 제한없음)


- - - - - - - - - - - - - - - Code begins here - - - - - - - - - - - - - - -
REM ------------------------------------------------------------------------
REM DISCLAIMER:
REM    This script is provided for educational purposes only. It is NOT 
REM    supported by Oracle World Wide Technical Support.
REM    The script has been tested and appears to work as intended.
REM    You should always run new scripts on a test instance initially.
REM ------------------------------------------------------------------------

CREATE OR REPLACE PACKAGE CryptIT AS
   FUNCTION encrypt( Str VARCHAR2, 
                     hash VARCHAR2 ) RETURN VARCHAR2;
   FUNCTION decrypt( xCrypt VARCHAR2,
                     hash VARCHAR2 ) RETURN VARCHAR2;
END CryptIT;
/

CREATE OR REPLACE PACKAGE BODY CryptIT AS
   crypted_string VARCHAR2(2000);

   FUNCTION encrypt( Str VARCHAR2, 
                     hash VARCHAR2 ) RETURN VARCHAR2 AS
   pieces_of_eight INTEGER := ((FLOOR(LENGTH(Str)/8 + .9)) * 8);

   BEGIN

      dbms_obfuscation_toolkit.DESEncrypt(
               input_string     => RPAD( Str, pieces_of_eight ),
               key_string       => RPAD(hash,8,'#'),
               encrypted_string => crypted_string );
      RETURN crypted_string;
   END;

   FUNCTION decrypt( xCrypt VARCHAR2,
                     hash VARCHAR2 ) RETURN VARCHAR2 AS
   BEGIN
      dbms_obfuscation_toolkit.DESDecrypt(
               input_string     => xCrypt,
               key_string       => RPAD(hash,8,'#'),
               decrypted_string => crypted_string );
      RETURN trim(crypted_string);
   END;
END CryptIT;
/

- - - - - - - - - - - - - - -  Code ends here  - - - - - - - - - - - - - - -


2) Encrypt하여 데이터 입력

drop table encrypt_table;
create table encrypt_table( id number, passwd varchar(10) );

insert into encrypt_table values( 1, CryptIT.encrypt('tiger', 'key_a'));
insert into encrypt_table values( 2, CryptIT.encrypt('tiger', 'key_b'));

3) Decrypt하여 데이터 조회

SQL> select id, passwd from encrypt_table where passwd = 'tiger';

no rows selected

-> 물론 Decrypt하지 않으면 암호화된 데이터와 비교된다.

주의) encrypt된 데이터를 화면에 출력하면, terminal emulator가 오작동할 수 있다.
      그럴 경우, terminal emulator 프로그램 종료 후 다시 시작.

SQL> col passwd format a60
SQL> select id, dump(passwd) passwd from encrypt_table;

        ID PASSWD
---------- -------------------------------------------------------------
         1 Typ=1 Len=8: 246,27,80,184,227,225,245,31
         2 Typ=1 Len=8: 175,231,213,125,85,223,46,133


-> 저장장치에 Encrypt된 값으로 저장된다.

select id, CryptIT.decrypt(passwd,'key_a') passwd
from encrypt_table
where CryptIT.decrypt(passwd,'key_a') = 'tiger';

        ID PASSWD
---------- -------------------------------------------------------------
         1 tiger

select id, CryptIT.decrypt(passwd,'key_b') passwd
from encrypt_table
where CryptIT.decrypt(passwd,'key_b') = 'tiger';

        ID PASSWD
---------- ------------------------------------------------------------
         2 tiger

-> Encrypt할 때 사용한 Key로만 Decrypt할 수 있다.

주의) Table에 접근 권한이 있는 다른 유저도 Key값을 알면 Decrypt할 수 있다.

4) 관련 ORA number
ORA error 28231 "Invalid input to Obfuscation toolkit"
- input data, key값이 NULL일 경우 발생

ORA error 28232 "Invalid input size for Obfuscation toolkit"
- input data가 8 bytes 배수가 아닐 경우 발생

ORA error 28233 "Double encryption not supported by DESEncrypt in Obfuscation toolkit"
- encrypt data를 다시 encrypt경우 발생


관 련 자 료
===========
Oracle8i Supplied PL/SQL Packages Reference Release 2 (8.1.6)

댓글 없음:

댓글 쓰기