더북(TheBook)

Knowhow | 암호화 키 관리 방법

암호화의 핵심은 암호화 키다. 아무리 안전한 알고리즘을 사용해 암호화했다 하더라도 암호화 키를 분실하거나 악의적 해커가 키를 획득한다면 암호화된 데이터는 언제든지 복호화할 수 있다. 정상적인 복호화를 위해서는 암호화 할 때 사용했던 키와 암호화 슈트를 사용해야 하는데, 암호화 슈트는 조합의 경우의 수가 얼마 되지 않기 때문에 알아내는데 그리 어렵지 않으므로 암호화 키의 관리가 그만큼 중요하다.

그럼 암호화 키는 어떻게 생성하고 관리하는 것이 좋을까? 앞서 본 예제에서는 RANDOMBYTES 함수를 사용해 무작위로 생성했는데 이렇게 처리하면 해당 익명 블록 내에서만 사용할 수 있다. 따라서 어딘가에는 암호화 키를 저장해 놓아야 나중에 복호화할 때 꺼내 쓸 수 있다.

암호화 키를 저장하는 몇 가지 방식을 산정하고 악의적인 해커가 임의의 사용자 계정을 탈취하여 DB에 접근이 가능한 경우, 발생 가능한 문제점을 정리해 보자.

① 임의 테이블의 한 컬럼에 저장한다

암호화 키가 저장된 테이블을 해커가 알아낸다면 암호화 데이터를 복호화 할 수 있다.

② 저장된 암호화 키 자체를 또 다시 암호화 해서 저장하고, 사용할 때는 다시 복호화해서 사용한다

암호화 키를 암호화한 두 번째 키도 해커에게 누출될 수 있고, 이 키를 획득한다면 해커가 암호화 키를 알아내는 것은 시간 문제이다.

③ 키를 테이블에 저장하는 것은 문제가 있으므로 패키지 상수로 선언해 사용한다

패키지 소스 역시 DB에 저장되며 DBA_SOURCE 뷰를 이용해 해당 패키지 소스를 볼 수 있으므로 이 역시 안전한 방법은 아니다.

세 가지 방법 모두 그리 안전해 보이지 않은데 도대체 어떻게 관리하면 좋을까? 암호화 키를 저장해 놓은 테이블의 권한(SELECT, INSERT, UPDATE, DELETE 권한)을 엄격히 제한해 놓으면 괜찮지 않을까? 그렇게 하더라도 악의적 해커가 권한이 높은 사용자 계정의 아이디와 비밀번호를 알고 있다면 무용지물이다.

따라서 보다 안전한 암호화 키 관리 방법은 패키지 상수로 관리를 하고 암호화와 복호화를 수행하는 프로그램도 패키지에 담은 다음 이 패키지 소스 자체를 숨기면 된다. 패키지 소스를 숨기는 방법은 DBMS_DDL 시스템 패키지의 CREATE_WRAPPED 프로시저를 이용한다.

DBMS_DDL.CREATE_WRAPPED 프로시저는 패키지 선언부, 패키지 본문, 함수, 프로시저, 타입 등을 정의하는 CREATE OR REPLCE PACKAGE문을 매개변수로 입력받아 소스를 숨기는 기능을 한다. 간단한 패키지를 만들어 테스트해 보자.

입력

    DECLARE
      vv_ddl VARCHAR2(1000); -- 패키지 소스를 저장하는 변수
    BEGIN
      -- 패키지 소스를 vv_ddl에 설정
      vv_ddl := 'CREATE OR REPLACE PACKAGE ch19_wrap_pkg IS
                 pv_key_string VARCHAR2(30) := ''OracleKey'';
                 END ch19_wrap_pkg;';

      -- CREATE_WRAPPED 프로시저를 사용하면 패키지 소스를 숨기는 것과 동시에 컴파일도 수행한다.
      DBMS_DDL.CREATE_WRAPPED ( vv_ddl );

    EXCEPTION WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END ;

결과

    익명 블록이 완료되었습니다.

그럼 이 패키지에 저장된 상수 값을 출력해 보자.

입력

    BEGIN
      DBMS_OUTPUT.PUT_LINE(ch19_wrap_pkg.pv_key_string);
    END;

결과

    OracleKey

제대로 컴파일되었고 상수 값도 제대로 가져왔다. 물론 ch19_wrap_pkg 패키지의 pv_key_string 상수에 암호화 키가 저장된 사실을 알고 있다면 CREATE_WRAPPED 프로시저를 사용해 소스를 숨기는 것도 무용지물이다. 하지만 암호화 키를 사용해 데이터를 암호화하고 복호화 하는 프로그램을 또 다른 패키지로 구현하고 이 패키지 전체를 숨기면 이 두 개의 패키지 제작자 이외에는 그 누구도 ch19_wrap_pkg.pv_key_string에 암호화 키가 저장된 사실을 알 수 없을 것이다. 그럼 ch19_wrap_pkg 패키지 소스가 제대로 숨겨져 있는지 확인해 보자. [그림 19-1]은 SQL Developer에서 ch19_wrap_pkg 소스를 본 화면이다.

다른 프로시저, 패키지와는 달리 CREATE_WRAPPED 프로시저를 사용한 ch19_wrap_pkg 패키지는 소스가 이상한 문자로 채워져 있어 이 패키지 개발자조차도 패키지 소스를 볼 수가 없다. 이런 식으로 암호화 프로그램까지 소스를 숨기면 암호화와 관련된 모듈 전체의 소스가 숨겨지므로 좀더 안전한 관리방식이라고 할 수 있다. 물론 악의적 해커가 ch19_wrap_pkg 패키지처럼 소스가 숨겨진 패키지만 골라 삭제하거나 임의로 소스를 변경해 재컴파일을 한다면 어찌할 도리가 없긴 하다.

그림 19-1 CREATE_WRAPPED 프로시저를 이용해 소스를 숨긴 ch19_wrap_pkg 패키지 소스
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.