ISMS AES-128 암호화키 관리
이전 글에선 WAS에서 jar모듈로 암호화키를 관리하는 포스팅을 올렸는데
오라클 스케줄러 내 호출하는 프로시저에서 암/복호화를 할 시 관리 방법에 대해 포스팅한다
서버 내 암호화키를 암호화하여 파일에 저장
오라클을 설치한 계정으로 폴더를 만들거나 root로 생성 후 오라클 계정에 폴더 권한을
부여해 접근할 수 있도록 설정
mkdir /home/oracle/enc_key
vi /home/oracle/enc_key/enc_key.txt
ED6CF66DAF90E7D9C6935E1B47643210791603D8B6745F0E31B2C14CFA31A3C7 입력
cat /home/oracle/enc_key/enc_key.txt
ED6CF66DAF90E7D9C6935E1B47643210791603D8B6745F0E31B2C14CFA31A3C7
오라클 UTL_FILE
UTL_FILE은 운영체제에서 관리하는 파일에 접근하기 위한 함수와 프로시저를 제공하는 패키지다
파일의 경로는 DIRECTORY로 접근할 수 있어 접근이 가능한지 확인한다
CREATE DIRECTORY ENC_KEY AS '/home/oracle/enc_key'
SELECT * FROM ALL_DIRECTORIES
생성한 파일에 접근 가능한지 확인.
DECLARE
FHANDLE UTL_FILE.FILE_TYPE;
FBUFFER VARCHAR2(64);
BEGIN
FHANDLE := UTL_FILE.FOPEN('ENC_KEY', 'enc_key.txt', 'R');
UTL_FILE.GET_LINE(FHANDLE, FBUFFER);
DBMS_OUTPUT.PUT_LINE(FBUFFER);
UTL_FILE.FCLOSE(FHANDLE);
END;
실행결과: ED6CF66DAF90E7D9C6935E1B47643210791603D8B6745F0E31B2C14CFA31A3C7
암호화키를 가져오는 ENCKEY 패키지 GET_ENC_KEY 함수를 생성
CREATE OR REPLACE PACKAGE TEST.ENCKEY
IS
FUNCTION GET_ENC_KEY RETURN VARCHAR2;
END ENCKEY;
CREATE OR REPLACE PACKAGE BODY TEST.ENCKEY
IS
FUNCTION GET_ENC_KEY RETURN VARCHAR2
IS
FHANDLE UTL_FILE.FILE_TYPE;
FBUFFER VARCHAR2(64);
INPUT_STRING VARCHAR2(64);
KEY_RAW RAW(16) := UTL_RAW.CAST_TO_RAW('test1234test1234');
OUTPUT_RAW RAW(1024);
V_OUT_STRING VARCHAR2(1024);
AES_CBC_PKCS5 CONSTANT PLS_INTEGER :=
DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5;
BEGIN
--CREATE DIRECTORY ENC_KEY AS '/home/oracle/enc_key'
--SELECT * FROM ALL_DIRECTORIES
FHANDLE := UTL_FILE.FOPEN('ENC_KEY', 'enc_key.txt', 'R');
UTL_FILE.GET_LINE(FHANDLE, FBUFFER, 64);
INPUT_STRING := FBUFFER;
UTL_FILE.FCLOSE(FHANDLE);
IF INPUT_STRING IS NULL THEN
RETURN NULL;
END IF;
OUTPUT_RAW := DBMS_CRYPTO.DECRYPT(
src => INPUT_STRING,
typ => AES_CBC_PKCS5,
key => KEY_RAW);
V_OUT_STRING := UTL_I18N.RAW_TO_CHAR(OUTPUT_RAW, 'AL32UTF8');
RETURN V_OUT_STRING;
END GET_ENC_KEY;
END ENCKEY;
패키지 함수 생성 후 잘 나오는지 확인
SELECT ENCKEY.GET_ENC_KEY FROM dual
오라클 DBMS_DDL
DBMS_DDL은 CREATE OR REPLACE PROCEDURE, PACKAGE로 시작하는 DDL 구문에 대한
WRAPPING 기능 외 기타 DDL 관련 기능을 제공하는 패키지이며
CREATE_WRAPPED 프로시저를 사용하면 패키지 소스를 숨기는 것과 동시에 컴파일도 수행한다
생성한 패키지 내용을 보면 GET_ENC_KEY 함수를 호출하면 암호화키를 얻을 수 있는 것을
알 수 있고 암호화키를 암/복호화하는 암호화키를 얻을 수 있기 때문에
선언부, 구현부 소스 모두 암호화 하여 평문의 소스는 별도 관리한다
varchar2는 최대길이가 4000byte기 때문에 긴 내용을 암호화 할 땐 CLOB 타입을 사용
(CLOB 최대길이 4GB)
DECLARE
src CLOB;
BEGIN
src :=
'
CREATE OR REPLACE PACKAGE TEST.ENCKEY
IS
FUNCTION GET_ENC_KEY RETURN VARCHAR2;
END ENCKEY;
';
DBMS_DDL.CREATE_WRAPPED (src);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END ;
DECLARE
src CLOB;
BEGIN
src :=
'
CREATE OR REPLACE PACKAGE BODY TEST.ENCKEY
IS
FUNCTION GET_ENC_KEY RETURN VARCHAR2
IS
FHANDLE UTL_FILE.FILE_TYPE;
FBUFFER VARCHAR2(64);
INPUT_STRING VARCHAR2(64);
KEY_RAW RAW(16) := UTL_RAW.CAST_TO_RAW(''test1234test1234'');
OUTPUT_RAW RAW(1024);
V_OUT_STRING VARCHAR2(1024);
AES_CBC_PKCS5 CONSTANT PLS_INTEGER :=
DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5;
BEGIN
--CREATE DIRECTORY ENC_KEY AS ''/home/oracle/enc_key''
--SELECT * FROM ALL_DIRECTORIES
FHANDLE := UTL_FILE.FOPEN(''ENC_KEY'', ''enc_key.txt'', ''R'');
UTL_FILE.GET_LINE(FHANDLE, FBUFFER, 64);
INPUT_STRING := FBUFFER;
UTL_FILE.FCLOSE(FHANDLE);
IF INPUT_STRING IS NULL THEN
RETURN NULL;
END IF;
OUTPUT_RAW := DBMS_CRYPTO.DECRYPT(
src => INPUT_STRING,
typ => AES_CBC_PKCS5,
key => KEY_RAW);
V_OUT_STRING := UTL_I18N.RAW_TO_CHAR(OUTPUT_RAW, ''AL32UTF8'');
RETURN V_OUT_STRING;
END GET_ENC_KEY;
END ENCKEY;
';
DBMS_DDL.CREATE_WRAPPED (src);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END ;
CREATE OR REPLACE PACKAGE BODY TEST.ENCKEY wrapped
a000000
369
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
b
346 258
d7fOkKhxMcBsoykWCbGefn3PBr0wg3lezPYFfC8ZCk7Vud6fEXwuYY1LJTdWT3bzLmXxaPdJ
f/K0ymMojCgFP3O5fsYK6+Z2Gvi5vHL+Vb6UwJarRpc9W2fV/jBUfUuFwxcBd//m1n/MevOm
HAvBYmiZlr8VIG+IF8knSX55L0UR8SU5DPkMCFAGYoxcsI6SJk1TOlNdU2F5H17jhwWLlFrg
+m0gZ64tvJMVwZhBkOJjjqjofc5xXbGwuyQ/+RDkgdLOuPK70LA0ZJ9Mkbn0jyOCSxlJ/kBd
Npl0oStlDRKIIjf136I476AbFHnv33c27YBMEGMhqhGM1fofIhTlcSBhuCod9Ey6GzTjxFEc
FFoDFWC68Rw/F+/GSFuWTG1hhca9XdWF0K4oKfXkXiK1P4sKLCNBnjCHYLpWYGGUX7ZUr7r/
tzzjclSJIdFZdoRYrJNjy3DaC8q5yLpXllvGV6R5sqNMX4YVnav4hDWhk280RpiWgvBcKFAb
f3z9cqml3NNlSNmb35h2m30ahyB5oYg0eHrSBrXV99YVz7T1zHkS73LV+awCUWhHbSg3Rldl
z9H1Qv4o30538w==
이런 식으로 암호화 되어 저장된다
함수 호출 시 잘 나오는지 확인
crypto.encrypt는 아래 포스팅에서 작성한 함수다
(Oracle DBMS_CRYPTO)
SELECT crypto.encrypt('개인정보', ENCKEY.GET_ENC_KEY) FROM dual
ENCKEY.GET_ENC_KEY를 호출하면 암호화키를 확인할 수 있기 때문에 해당 함수를 호출하는
모든 프로시저를 암호화(wrap)해야 한다고 하여 위와 마찬가지로 CLOB타입으로 전부 처리했다