본문 바로가기

DB/Oracle

오라클 DBMS_CRYPTO 암호화

DBMS_CRYPTO를 이용한 암호화 테스트 - AES를 이용한 암호화 (오라클 10G 이상)

 

1. 사전 권한 부여

- 데이터의 암호화 및 복호화를 할려면 아래와같은 권한을 부여받아야한다.
  SYS 계정으로 로그인 후 아래의 권한을 준다.

--GRANT EXECUTE ON DBMS_OBFUSCATION_TOOLKIT TO PUBLIC;

GRANT EXECUTE ON DBMS_OBFUSCATION_TOOLKIT TO USER_NAME;
--GRANT EXECUTE ON DBMS_CRYPTO TO PUBLIC;

GRANT EXECUTE ON DBMS_CRYPTO TO USER_NAME;

 

2. 관련 패키지 소스
-- HEAD

CREATE OR REPLACE PACKAGE SYSADM.ENCRYPTION_AES
IS

/******************************************************************************
  암호화
 ******************************************************************************/
 FUNCTION ENC_AES ( INPUT_STRING IN VARCHAR2
 ) RETURN VARCHAR2;
 
/******************************************************************************
  복호화
 ******************************************************************************/
 FUNCTION DEC_AES ( INPUT_STRING IN VARCHAR2
 ) RETURN VARCHAR2;
                      
END ENCRYPTION_AES;
/

 

-- BODY

CREATE OR REPLACE PACKAGE BODY SYSADM.ENCRYPTION_AES
IS

/******************************************************************************
  암호화
 ******************************************************************************/
 FUNCTION ENC_AES ( INPUT_STRING IN VARCHAR2
 ) RETURN VARCHAR2
 IS

    V_ORIGINAL_RAW      RAW(13);        -- 암호화 전 데이타
    V_KEY_DATA_RAW      RAW(64);        -- 키값
    ENCRYTED_RAW        RAW(32);        -- 암호화 된 데이타
    CONVERTED_STRING    VARCHAR2(32);   -- 형 변환 데이타

    BEGIN
    
        V_ORIGINAL_RAW   := UTL_I18N.STRING_TO_RAW(INPUT_STRING, 'AL32UTF8');         -- VARCHAR2 -> RAW 타입으로 변경 (변경 이유는 아래에..)        
        V_KEY_DATA_RAW   := UTL_I18N.STRING_TO_RAW('AKDKEKDKFKGKEKSD', 'AL32UTF8');   -- 키값 RAW 타입으로 변경.
        ENCRYTED_RAW     := DBMS_CRYPTO.ENCRYPT( SRC => V_ORIGINAL_RAW,
                                                    TYP => DBMS_CRYPTO.ENCRYPT_AES128 + 
                                                           DBMS_CRYPTO.CHAIN_CBC + 
                                                           DBMS_CRYPTO.PAD_PKCS5,
                                                    KEY => V_KEY_DATA_RAW );
        CONVERTED_STRING := UTL_RAW.cast_to_varchar2( utl_encode.base64_encode(ENCRYTED_RAW) ) ;

        -- 중요!!! raw 타입을 base64_encode()를 이용하여 encoding 후 varchar2 타입으로 변환해야한다!! 해주지 않으면
        -- ORA-06502: PL/SQL: numeric or value error: hex to raw conversion error 이러한 에러를 볼 수 있을 것이다.

        RETURN CONVERTED_STRING;
        
    END ENC_AES;
/******************************************************************************
  암호화 끝
 ******************************************************************************/

/******************************************************************************
  복호화
 ******************************************************************************/
 FUNCTION DEC_AES (  INPUT_STRING IN VARCHAR2
 ) RETURN VARCHAR2
 IS
    
    V_KEY_DATA_RAW      RAW(64);        -- 키값
    DECRYPTED_RAW       RAW(32);        -- 복호화 값
    CONVERTED_STRING    VARCHAR2(32);   -- 형 변환 데이타

    BEGIN
    
        V_KEY_DATA_RAW := UTL_I18N.STRING_TO_RAW('AKDKEKDKFKGKEKSD', 'AL32UTF8');
        DECRYPTED_RAW :=  DBMS_CRYPTO.DECRYPT( SRC => utl_encode.base64_decode(utl_raw.cast_to_raw(INPUT_STRING)), 
        -- 중요!!! varchar2 타입의 데이타를 raw 타입으로 변환 후 decoding 해야한다!! 해주지 않으면
        -- ORA-06502: PL/SQL: numeric or value error: hex to raw conversion error 이러한 에러를 볼 수 있을 것이다.
                                                  TYP => DBMS_CRYPTO.ENCRYPT_AES128 + 
                                                         DBMS_CRYPTO.CHAIN_CBC +
                                                         DBMS_CRYPTO.PAD_PKCS5,
                                                  KEY => V_KEY_DATA_RAW );                                                                             
        CONVERTED_STRING :=  UTL_I18N.RAW_TO_CHAR(DECRYPTED_RAW, 'AL32UTF8');  -- RAW -> CHAR 타입으로 변환하여 RETURN
                                         
        RETURN CONVERTED_STRING;
        
    END DEC_AES;
/******************************************************************************
  복호화 끝
 ******************************************************************************/

END ENCRYPTION_AES;
/

 

3. 암호화 패키지를 이용한 암호화 테스트

UPDATE DEC_TEST
   SET RECT_AES = ENCRYPTION_AES.ENC_AES(RECT_NO)
 WHERE RECT_NO  = '991231-1000000';

 

4. 암호화 패키지를 이용한 복호화 테스트

SELECT RECT_NO, ENCRYPTION_AES.DEC_AES(RECT_AES)
  FROM DEC_TEST
 WHERE RECT_NO = '991231-1000000';

 

5. KEY SIZE

128-BIT(16 BYTE)

 

6. 참고

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_crypto.htm#i1004271


출처 | http://blog.naver.com/killhani1/20128126177