수작업 애플리케이션 암호화 구현

DBMS_OBFUSCATION_TOOLKIT

  • 8i ~ 10g, DES( Data Encryption Standard ) 와 3DES( Triple DES ) 암호화 알고리즘 채택
  • 데이터의 MD5 체크섬을 생성 할 수 있다.
  • RAW 와 VARCHAR 데이터타입에서만 작동

DBMS_CRYPTO

  • 현재 지원되는 암호화 API
  • DES, 3DES, RC4( Rivest Cipher 4 ), AES( advanced Encryption Standard ) 암호화 알고리즘 지원
  • 해시 와 MD5, MD4, SHA-1과 같은 MAC( message authentication codes, 메세지 인증 코드 )를 생성하는 기능
  • RAW, CLOB, BLOB 데이터 타입 가능

수작업 방법을 피해야 하는 이유

  • 암호화 키 관리 및 책임
  • 암복화 루틴을 코딩
  • 성능상의 영향도 파악
  • 암호화 대상 컬럼을 RAW 데이터 타입으로 변환 : 암호화 데이터가 바이너리
  • VARCHAR2(70) -> RAW(80) : 16바이트 * 5

수작업 방법의 성능 영향


SQL> GRANT EXECUTE ON DBMS_CRYPTO TO SCOTT;

권한이 부여되었습니다.

SQL>
SQL> create or replace package scott.encryption_wrapper
  2  as
  3    function encrypt( p_string in varchar2, p_key in varchar2 ) return raw;
  4    function decrypt( p_raw in raw, p_key in varchar2 ) return VARCHAR2;
  5  end;
  6  /

패키지가 생성되었습니다.

SQL> create or replace package body scott.encryption_wrapper
  2  as
  3    g_encrypt_typ constant PLS_INTEGER default DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5;
  4    FUNCTION PADKEY( P_KEY IN VARCHAR2 ) RETURN RAW
  5    IS
  6    BEGIN
  7      RETURN UTL_RAW.CAST_TO_RAW( RPAD( P_KEY, 32 ) );
  8    END;
  9    FUNCTION ENCRYPT( P_STRING IN VARCHAR2, P_KEY IN VARCHAR2 ) RETURN RAW
 10    IS
 11    BEGIN
 12      RETURN DBMS_CRYPTO.ENCRYPT( SRC => UTL_I18N.STRING_TO_RAW( P_STRING, 'AL32UTF8' ),
 13                                  TYP => G_ENCRYPT_TYP,
 14                                  KEY => PADKEY( P_KEY ) );
 15    END;
 16    function decrypt( p_raw in raw, p_key in varchar2 ) return VARCHAR2
 17    IS
 18    BEGIN
 19      RETURN UTL_I18N.RAW_TO_CHAR( DBMS_CRYPTO.DECRYPT(
 20                                                      SRC => p_raw,
 21                                                      TYP => G_ENCRYPT_TYP,
 22                                                      KEY => PADKEY( P_KEY )
 23                                                      )
 24                                  , 'AL32UTF8');
 25    END;
 26  END;
 27  /

패키지 본문이 생성되었습니다.

SQL>
SQL> create table scott.stage
  2  as
  3  select object_name from all_objects;

테이블이 생성되었습니다.

SQL> create table scott.t
  2  ( last_name varchar2( 30 ),
  3    encrypted_name raw(32)  -- 2 * 16
  4  )
  5
SQL> /
SQL> truncate table scott.t;
-- 비 암호화 Loop
SQL> declare
  2    l_start number := dbms_utility.get_cpu_time;
  3  begin
  4    for x in (select object_name from scott.stage)
  5    loop
  6      insert into scott.t ( last_name ) values ( x.object_name );
  7    end loop;
  8    dbms_output.put_line( (dbms_utility.get_cpu_time-l_start) || ' hsecs');
  9  end;
 10  /

PL/SQL 처리가 정상적으로 완료되었습니다.

경   과: 00:00:09.66  -- serveroutput on 음..;;

SQL> truncate table scott.t;
-- 암호화 Loop
SQL> declare
  2    l_start number := dbms_utility.get_cpu_time;
  3  begin
  4    for x in (select object_name from scott.stage)
  5    loop
  6      insert into scott.t ( encrypted_name )
  7      values ( scott.encryption_wrapper.encrypt( x.object_name, 'jhlee68' ) );
  8    end loop;
  9    dbms_output.put_line( (dbms_utility.get_cpu_time-l_start) || ' hsecs');
 10  end;
 11  /

PL/SQL 처리가 정상적으로 완료되었습니다.

경   과: 00:00:33.79
SQL>
SQL> truncate table scott.t;
-- 비 암호화 INSERT AS SELECT
SQL> declare
  2    l_start number := dbms_utility.get_cpu_time;
  3  begin
  4    insert into scott.t ( last_name ) select object_name from scott.stage;
  5    dbms_output.put_line( (dbms_utility.get_cpu_time-l_start) || ' hsecs');
  6  end;
  7  /

PL/SQL 처리가 정상적으로 완료되었습니다.

경   과: 00:00:00.17
SQL>
SQL> truncate table scott.t;
-- 암호화 INSERT AS SELECT
SQL> declare
  2    l_start number := dbms_utility.get_cpu_time;
  3  begin
  4    insert into scott.t ( encrypted_name )
  5    select scott.encryption_wrapper.encrypt( object_name, 'jhlee68' )
  6    from scott.stage;
  7    dbms_output.put_line( (dbms_utility.get_cpu_time-l_start) || ' hsecs');
  8  end;
  9  /

PL/SQL 처리가 정상적으로 완료되었습니다.

경   과: 00:00:11.77


  • 조회
    {CODE:SQL}
    SQL> truncate table scott.t;

테이블이 잘렸습니다.

경 과: 00:00:00.06
SQL>
SQL>
SQL> insert into scott.t ( last_name, encrypted_name )
2 select object_name
3 , scott.encryption_wrapper.encrypt( object_name, 'jhlee68' )
4 from scott.stage;

84190개의 행이 생성되었습니다.

경 과: 00:00:11.47
SQL>
SQL>
SQL> COMMIT;

커밋이 완료되었습니다.

경 과: 00:00:00.01
SQL>
-- 일반적이 셀렉트
SQL> declare
2 l_start number := dbms_utility.get_cpu_time;
3 begin
4 for x in (select last_name from scott.t)
5 loop
6 null;
7 end loop;
8 dbms_output.put_line( (dbms_utility.get_cpu_time-l_start) || ' hsecs');
9 end;
10 /

PL/SQL 처리가 정상적으로 완료되었습니다.

경 과: 00:00:00.17
SQL>
-- 복호화 셀렉트
SQL> declare
2 l_start number := dbms_utility.get_cpu_time;
3 begin
4 for x in (select scott.encryption_wrapper.decrypt( encrypted_name, 'jhlee68' )
5 from scott.t)
6 loop
7 null;
8 end loop;
9 dbms_output.put_line( (dbms_utility.get_cpu_time-l_start) || ' hsecs');
10 end;
11 /

PL/SQL 처리가 정상적으로 완료되었습니다.

경 과: 00:00:11.26
SQL>
{CODE}

수작업 방법 사용 시점

  • ASO( Advanced Security Option ) 를 지원하지 않는 오라클 Standard Edition( SE ) : 개발비용발생