반응형
암호화 복호화는 테스트 하고 설명하자면 끝도 없지만.
간단한 샘플 package 를 만들어서 직접 테스트 해 보면 그렇게 어렵지는 않다.
아래 관련자료 첨부하였으니
일단 한 번 수행 시켜서 수행해보고 이해해 보면 되겠다.
[by sinu] dbms_obfuscation_toolkit.txt 는 설명없이 스크립트만 들어 있으니 그냥 복사해서 붙이면 되고
(user 생성 및 clean 까지 되어 있다.)
[spool] dbms_obfuscation_toolkit.log 는 위 스크립트의 spool 결과이다.
수행여건이 안되거나 귀찮으신 분들을 위해;;
세세한 사항은 스크립트를 보면 되고
중요한 부분만 간략하게 설명하도록 하겠다.
8i, 9i 와 같은 경우 dbms_obfuscation_toolkit 만 사용이 가능한데
아래처럼 실행 권한만 부여해 주면 된다.
grant execute on dbms_obfuscation_toolkit to sinu;
패키지 생성 소스를 살펴 보자
CREATE OR REPLACE PACKAGE pkg_obfus
IS
FUNCTION encrypt (
input_string IN VARCHAR2 ,
key_data IN VARCHAR2 := '1122334455667788'
) RETURN RAW;
FUNCTION decrypt (
input_string IN VARCHAR2 ,
key_data IN VARCHAR2 := '1122334455667788'
) RETURN VARCHAR2;
END pkg_obfus;
/
이 부분 부터가 패키지 바디 소스이다.
CREATE OR REPLACE PACKAGE BODY pkg_obfus
IS
-- 에러 발생시에 error code 와 message 를 받기 위한 변수 지정.
SQLERRMSG VARCHAR2(255);
SQLERRCDE NUMBER;
-- 암호화 함수 선언 key_data 는 입력하지 않을 시에 default 로 1122334455667788 로 지정됨.
FUNCTION encrypt (input_string IN VARCHAR2 , key_data IN VARCHAR2 := '1122334455667788')
RETURN RAW
IS
key_data_raw RAW(128);
input_string_raw RAW(128);
encrypted_raw RAW(2048);
BEGIN
-- 들어온 data 와 암호키를 각각 RAW 로 변환한다.
input_string_raw := UTL_RAW.CAST_TO_RAW(input_string);
key_data_raw := UTL_RAW.CAST_TO_RAW(key_data);
-- DES 방식으로 암호화 한다.
dbms_obfuscation_toolkit.DESEncrypt(
input => input_string_raw,
key => key_data_raw,
encrypted_data => encrypted_raw );
-- dbms_obfuscation_toolkit 를 수행하면 encrypted_raw 에 암호화된 data 가 raw 형태로 저장된다.
-- 암호화된 data 를 return (생각보다 간단하지 않은가?)
RETURN encrypted_raw;
END encrypt;
FUNCTION decrypt (input_string IN VARCHAR2 , key_data IN VARCHAR2 := '1122334455667788')
RETURN VARCHAR2
IS
converted_string VARCHAR2(48);
key_data_raw RAW(128);
decrypted_raw VARCHAR2(2048);
BEGIN
key_data_raw := UTL_RAW.CAST_TO_RAW(key_data);
-- 복호화 역시 간단하다. input_string 자체가 RAW 이므로 convert 하지 않아도 된다.
dbms_obfuscation_toolkit.DESDecrypt(
input => input_string,
key => key_data_raw,
decrypted_data => decrypted_raw);
-- return 형태는 RAW 이므로 이를 다시 varchar2 로 변환하여 리턴한다.
converted_string := UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw);
RETURN converted_string;
END decrypt ;
END pkg_obfus;
/
-- 암호화된 컬럼에 index 생성이 가능하다!!
create table card_info ( id number, card_number varchar(32) primary key) ;
insert into card_info values ( 1 , pkg_obfus.encrypt('1234567812345678'));
-- 2nd argument 에 원하는 key 값을 넣을 수도 있다.
insert into card_info values ( 2 , pkg_obfus.encrypt('1234567812345678', '0000111122223333'));
commit;
-- 같은 데이터 1234567812345678 을 넣었으나 key 값이 다르기 때문에 값이 전혀 다르다.
select * from card_info;
ID CARD_NUMBER
---------- --------------------------------
1 365C80EABBC8859E91C4BDE4B3C52A4B
1 858B176DA8B125034356364E8179CD61
-- 2 번째 data 의 경우 key 값이 틀리기 때문에 복호화 되지 않고 에러를 뿌려준다.
select id, pkg_obfus.decrypt(card_number) card_number from card_info;
ID CARD_NUMBER
---------- --------------------------------------------------
1 1234567812345678
SP2-0784: Invalid or incomplete character beginning 0xF1 returned
-- 2 번째 row 의 key 값을 제대로 넣어주자 정상적으로 보인다.
select id, pkg_obfus.decrypt(card_number, '0000111122223333') card_number from card_info;
SP2-0784: Invalid or incomplete character beginning 0xEB returned
ID CARD_NUMBER
---------- --------------------------------------------------
2 1234567812345678
-- [퀴즈] 특정 data 를 select 하려면 where 절에 어떤 형식으로 값을 주어야 할까?
1. select * from card_info where card_number = '1234567812345678';
2. select * from card_info where card_number = utl_raw.cast_to_raw('1234567812345678');
3. select * from card_info where card_number = '365C80EABBC8859E91C4BDE4B3C52A4B';
4. select * from card_info where card_number = pkg_obfus.encrypt('1234567812345678');
정답은 : 3 , 4 번 (드래그 하세요~)
소스는 길고 복잡해도
포인트는
dbms_obfuscation_toolkit.DESEncrypt
dbms_obfuscation_toolkit.DESDecrypt
요 2가지 이고 나머지는 그냥 varchar2 와 raw 의 converting 작업이다.
나머지 세세한 사항은 메뉴얼을 참고하자!