라이프로그


DBMS_OBFUSCATION_TOOLKIT 의 암호화/복호화 IT

Oracle 8i Release2 (8.1.6) 부터 향상된 보안 기능으로 DBMS_OBFUSCATION_TOOLKIT 을 사용한 암호화 복호화 기능이 있다. 이 기능은 DB 내에 저장되는 컬럼을 plain 문장이 아닌 암호화된 문장을 저장할 수 있게 한다. 만약 신용카드 번호나 패스워드 등 안전하게 보호해야 할 정보일 경우 이 기능을 사용하면 안전하게 정보를 저장할 수 있다. 기존에는 암호화 기능을 사용하려면 3rd party의 제품이 필요했으나, 8.1.6 이후로는 DB 내에 이 기능을 포함시켰다.
DBMS_OBFUSCATION_TOOLKIT 을 사용하여 Data를 암호화/복호화한다.
이 패키지에는 4개의 프로시져가 있다.

* VARCHAR2와 RAW Data를 암호화하는 2개의 프로시져
* VARCHAR2와 RAW Data를 복호화하는 2개의 프로시져

설치 : 1) SYS 로 접속 후 dbmsobtk.sql과 prvtobtk.plb를 순서대로 실행 2) grant execute on dbms_obfuscation_toolkit to public

./opt/oracle/app/oracle/product/816/rdbms/admin/dbmsobtk.sql
./opt/oracle/app/oracle/product/816/rdbms/admin/prvtobtk.plb
보통 위의 위치에 있으며
위의 디렉토리로 이동 후 SQLPLUS에 들어가서
start dbmsobtk;
start prvtobtk.plb;
를 실행하면 설치할 수 있다.




이 function에서 일반적으로 2개의 파라미터가 필요하나데, 하나는 암호화되거나 복호화되는 데이타이고, 다른 하나는 암호화 알고리즘에서 사용되는 암호화 키이다.
DES (Data Encryption Standard) ===============================
DES 알고리즘은 64bit의 캐릭터를 사용하여 알파벳 한 글자 단위로 위치를 바꾸는 방식이며 19 단계를 거치게 된다. 복호화시 사용되는 패스워드는 암호화에 사용된 패스워드와 같으며, 그 역순을 따르게 된다. 입력 데이타는 8 캐릭터의 블럭으로 나뉘어져 각각 암호화 되며, dbms_obfuscation_toolki 에서 사용가능한 알고리즘이다.
사용 예제는 아래에 있다.
제약사항: ============
1) Data 는 DES (Data Encryption Standard) 에 의한 비밀키 암호화만 가능하며, 복호화시에도 동일한 키를 사용해야만 복호화가 가능하다. 2) 56 bit의 키를 사용한 암호화만 가능하다. 3) Double encryption은 지원하지 않으며, 암호화된 Data를 재암호화하려고 하면 ORA-28233 : "double encryption not supported" 에러가 발생한다.
이 제약사항들은 버젼 업그레이드에 따라 향상될 계획이며, 좀 더 강력한 보안 기능을 제공하게 될 것이다. 주의 사항 중 하나는 암호화/복호화 작업은 CPU 자원을 많이 사용하며, 시스템 가용 상황에 따라 적절한 계획을 세워야 할 것이다.
예제: ========
-- encrypt.sql
-- dbms_obfuscation_toolkit 를 사용한 예제
-- 입력한 데이타를 암호화한 값과 다시 복호화한 값을 출력

set serveroutput on;
CLEAR BUFFER
PROMPT Please enter a password - Must be 8 characters !
PROMPT
ACCEPT PASSWD

DECLARE
input_string VARCHAR2(16) := '&PASSWD';
raw_input RAW(128) := UTL_RAW.CAST_TO_RAW(input_string);
key_string VARCHAR2(16) := 'keepthesecretnum';
raw_key RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
encrypted_raw RAW(2048);
encrypted_string VARCHAR2(2048);
decrypted_raw RAW(2048);
decrypted_string VARCHAR2(2048);
error_in_input_buffer_length EXCEPTION;
PRAGMA EXCEPTION_INIT(error_in_input_buffer_length, -28232);
INPUT_BUFFER_LENGTH_ERR_MSG VARCHAR2(100) :=
'*** DES INPUT BUFFER NOT A MULTIPLE OF 8 BYTES - IGNORING EXCEPTION ***';
double_encrypt_not_permitted EXCEPTION;
PRAGMA EXCEPTION_INIT(double_encrypt_not_permitted, -28233);
DOUBLE_ENCRYPTION_ERR_MSG VARCHAR2(100) :=
'*** CANNOT DOUBLE ENCRYPT DATA - IGNORING EXCEPTION ***';

-- 1. Begin testing raw data encryption and decryption
BEGIN
dbms_output.put_line('> ========= BEGIN TEST RAW DATA =========');
dbms_output.put_line('> Raw input : ' ||
UTL_RAW.CAST_TO_VARCHAR2(raw_input));
BEGIN
dbms_obfuscation_toolkit.DESEncrypt(input => raw_input,
key => raw_key, encrypted_data => encrypted_raw );
dbms_output.put_line('> encrypted hex value : ' ||
rawtohex(encrypted_raw));
dbms_obfuscation_toolkit.DESDecrypt(input => encrypted_raw,
key => raw_key, decrypted_data => decrypted_raw);
dbms_output.put_line('> Decrypted raw output : ' ||
UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw));
dbms_output.put_line('> ');
if UTL_RAW.CAST_TO_VARCHAR2(raw_input) =
UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw) THEN
dbms_output.put_line('> Raw DES Encyption and Decryption successful');
END if;
EXCEPTION
WHEN error_in_input_buffer_length THEN
dbms_output.put_line('> ' || INPUT_BUFFER_LENGTH_ERR_MSG);
END;
dbms_output.put_line('> ');
END;
/


Result:
=======

SQL> start encrypt
Please enter a password - Must be 8 characters !

wildwind
old 2: input_string VARCHAR2(16) := '&PASSWD';
new 2: input_string VARCHAR2(16) := 'wildwind';
> ========= BEGIN TEST RAW DATA =========
> Raw input : wildwind
> encrypted hex value : 28EAA8E9E2CEA710
> Decrypted raw output : wildwind
>
> Raw DES Encyption and Decryption successful


PL/SQL procedure successfully completed.

화면 출력을 위해서는


SET ServerOutput ON

가 필요함

테스트용 procedure

CREATE OR REPLACE PROCEDURE
Test_encrypt_data(l_string in VARCHAR2, l_key in varchar2)
as
l_data varchar2(2000);
Key_check_flag number;
l_encrypted_string varchar2(2000);
BEGIN
--- the key and the input data must have a length
-- divisible by eight (the key must be exactly 8 bytes long).
--
l_data := RPAD(l_string,(TRUNC(LENGTH(l_string)/8)+1)*8,CHR(0));
key_check_flag := mod(length(l_key),8);
if key_check_flag != 0 then
Raise_application_error(-20199,'Key should be 8 char long');
end if;
--
-- Encrypt the input string
--
DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT
(input_string => l_data,
key_string => l_key,
encrypted_string => l_encrypted_string);
--
DBMS_OUTPUT.PUT_LINE('l_string ENCRYPTED: ' || l_encrypted_string);
--
--
END;
/


------------------------------------------------------------------
DBMS_OBFUSCATION_TOOLKIT.MD5의 사용예는 다음과 같습니다.
DECLARE
PLAIN_PASSWORD VARCHAR2(20) := 'SAMLPLE';
SECURE_PASSWORD VARCHAR2(32);
BEGIN
SECURE_PASSWORD := DBMS_OBFUSCATION_TOOLKIT.MD5(input_string=> PLAIN_PASSWORD);
END;

PL/SQL이나 Stored Procedure/Function에서는 위와 같이 사용하시면 됩니다.

여기서 주의하실점은, DBMS_OBFUSCATION_TOOLKIT에 MD5함수 정의가
overload되어있어서(RAW입력과 VARCHAR2입력에 대한 함수 2개가 정의) 그냥

SECURE_PASSWORD := DBMS_OBFUSCATION_TOOLKIT.MD5(PLAIN_PASSWORD);

이렇게 호출하면 오류가 난다는 겁니다. 반드시 parameter명 (VARCHAR2입력의 경우input_string)을 명시해야 원하는 함수를 호출할 수 있습니다.

트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://charie.pe.kr/tb/1057841 [도움말]