* 데이터의 암호화 및 복호화
1) 데이터의 암호화 및 복호화를 하려면 SYS로 부터 아래와 같은 권한을 부여 받야하 한다.
GRANT EXECUTE ON DBMS_CRYPTO TO NEWSCOTT;
[ 실행화면 ]
2) 암호화 및 복호화를 해주는 패키지를 작성한다.
CREATE OR REPLACE PACKAGE PACK_ENCRYPTION_DECRYPTION
IS
FUNCTION FUNC_ENCTYPT -- 암호화 하는 함수
(V_INPUT_STRING IN VARCHAR2
,KEY_DATA IN VARCHAR2 := 'JAVA302$' -- 이 값을 알아야만 암호화 가능,
)RETURN RAW; -- 리턴형은 원시형으로 설정
FUNCTION FUNC_DECRYPT -- 복호화 하는 함수
(V_INPUT_STRING IN VARCHAR2
,KEY_DATA IN VARCHAR2 := 'JAVA302$'
)RETURN VARCHAR2;
END PACK_ENCRYPTION_DECRYPTION;
[ 실행화면 ]
3) 위에서 만든 패키지에 바디 생성
CREATE OR REPLACE PACKAGE BODY PACK_ENCRYPTION_DECRYPTION
IS
FUNCTION FUNC_ENCRYPT -- 암호화 하는 함수
(V_INPUT_STRING IN VARCHAR2
,KEY_DATA IN VARCHAR2 := 'JAVA302$'
) RETURN RAW
IS
V_ORIGNAL_RAW RAW(64); -- RAW타입 변수 선언 법.
V_KEY_DATA_RAW RAW(64);
ENCRYTED_RAW RAW(64);
BEGIN
-- V_INPUT_STRING을 아래와 같이 RAW 타입으로 변경해줘야 한다.
V_ORIGNAL_RAW := UTL_I18N.STRING_TO_RAW(V_INPUT_STRING,'AL32UTF8');
-- KEY_DATA 또한 RQW 타입으로 변경
V_KEY_DATA_RAW := UTL_I18N.STRING_TO_RAW(KEY_DATA, 'AL32UTF8');
ENCRYTED_RAW := DBMS_CRYPTO.ENCRYPT(SRC => V_ORIGNAL_RAW,
TYP => DBMS_CRYPTO.DES_CBC_PKCS5,
KEY => V_KEY_DATA_RAW,
IV => NULL
);
-- 여기서 =>는 := 과 같은 의미로 본다.
RETURN ENCRYTED_RAW; -- 암호회 되어진 결과를 리턴.
END FUNC_ENCRYPT;
FUNCTION FUNC_DECRYPT -- 복호화 하는 함수
(V_INPUT_STRING IN VARCHAR2
,KEY_DATA IN VARCHAR2 := 'JAVA302$'
) RETURN VARCHAR2
IS
V_KEY_DATA_RAW RAW(64);
DECRYPTED_RAW RAW(64);
CONVERTED_STRING VARCHAR2(64);
BEGIN
V_KEY_DATA_RAW := UTL_I18N.STRING_TO_RAW(KEY_DATA, 'AL32UTF8');
DECRYPTED_RAW := DBMS_CRYPTO.DECRYPT(SRC => V_INPUT_STRING,
TYP => DBMS_CRYPTO.DES_CBC_PKCS5,
KEY => V_KEY_DATA_RAW,
IV => NULL
);
-- RAW 타입을 STRING 타입으로 변경
CONVERTED_STRING := UTL_I18N.RAW_TO_CHAR(DECRYPTED_RAW, 'AL32UTF8');
RETURN CONVERTED_STRING; -- 복호화된 결과를 리턴
END FUNC_DECRYPT; -- 복호화 함수 종료
END PACK_ENCRYPTION_DECRYPTION;
@ 테스를 위한 테이블 생성
CREATE TABLE TBL_NEWMEMBER
(ID VARCHAR2(10)
,PASSWD RAW(64)
,NAME VARCHAR2(10)
,JUBUN RAW(64)
,CONSTRAINT TBL_NEWMEMBER_ID_PK PRIMARY KEY(ID)
); -- 저장되는 공간인 테이블은 RAW 타입으로 해야한다.
SELECT *
FROM TBL_NEWMEMBER;
[ 테이블 확인 ]
@ 테이블에 암호화 함수 호출한뒤 INSERT 프로시져 생성
CREATE OR REPLACE PROCEDURE PCD_TBL_NEWMEMBER_INSERT
(V_ID IN TBL_NEWMEMBER.ID%TYPE
,V_PASSWD IN VARCHAR2
,V_NAME IN TBL_NEWMEMBER.NAME%TYPE
,V_JUBUN IN VARCHAR2
) -- 입력받는 변수 타입은 VARCHAR2로 한다.
IS
BEGIN
INSERT INTO TBL_NEWMEMBER VALUES(V_ID,
PACK_ENCRYPTION_DECRYPTION.FUNC_ENCRYPT(V_PASSWD),
V_NAME,
PACK_ENCRYPTION_DECRYPTION.FUNC_ENCRYPT(V_JUBUN));
END;
[ 결과 확인 ]
EXEC PCD_TBL_NEWMEMBER_INSERT('KIMWC', 'JAVA302$', '김위천', '7310121234567');
EXEC PCD_TBL_NEWMEMBER_INSERT('KIMTWOGYO', 'ABCD', '김이교', '8410121234567');
SELECT *
FROM TBL_NEWMEMBER;
@ 아이디를 입력받아 회원이 입력했던 본래 정보를 추출하고자 한다.
단 아이디를 입력받지 않았을 경우에는 모든 회원에 정보를 추출한다. " 복화화 "
CREATE OR REPLACE PROCEDURE PCD_TBL_NEWMEMBER_SELECT
(V_ID IN TBL_NEWMEMBER.ID%TYPE := NULL)
IS
TYPE CURSOR_TYPE -- REF CURSOR TYPE 선언
IS REF CURSOR;
V_CUR CURSOR_TYPE ; -- REF CURSOR TYPE 변수 선언
V_SQL_STMT VARCHAR2(500) :=
'SELECT ID,
PACK_ENCRYPTION_DECRYPTION.FUNC_DECRYPT(PASSWD),
NAME,
PACK_ENCRYPTION_DECRYPTION.FUNC_DECRYPT(JUBUN)
FROM TBL_NEWMEMBER';
TYPE RCD_TYPE -- RECORD TYPE 선언
IS RECORD
(ID VARCHAR2(10)
,PASSWD VARCHAR2(500)
,NAME VARCHAR2(10)
,JUBUN CHAR(13)
);
V_ALL RCD_TYPE; -- RECORD TYPE 변수 선언
BEGIN
IF V_ID IS NOT NULL THEN -- 아이디가 입력된 경우
V_SQL_STMT := V_SQL_STMT || ' WHERE ID = '''||V_ID||'''';
END IF;
OPEN V_CUR -- 변수 V_SQL_STMT 에 내용을 닮고 잇는 커서
FOR V_SQL_STMT;
LOOP
FETCH V_CUR INTO V_ALL;
EXIT WHEN V_CUR%NOTFOUND;
IF V_CUR%ROWCOUNT = 1 THEN
DBMS_OUTPUT.PUT_LINE( LPAD('-', 30, '-') );
DBMS_OUTPUT.PUT_LINE( '아이디 암호 성명 주민번호' );
DBMS_OUTPUT.PUT_LINE( LPAD('-', 30, '-') );
END IF;
DBMS_OUTPUT.PUT_LINE( V_ALL.ID || ' ' || V_ALL.PASSWD || ' ' ||
V_ALL.NAME || ' ' || V_ALL.JUBUN );
END LOOP;
CLOSE V_CUR;
END;
[ 실행화면 ]
EXEC PCD_TBL_NEWMEMBER_SELECT;
[ 실행결과 ]
@ 아이디와 비밀버호를 입력받아 로그인 시켜주는 프로시져 생성
CREATE OR REPLACE PROCEDURE PCD_LOGINCK
(V_ID IN VARCHAR2
,V_PASSWD_INPUT IN VARCHAR2) -- 실제로 입력한 비밀번호 받음.
IS
V_PASSWD_OUTPUT TBL_NEWMEMBER.PASSWD%TYPE; --= VARCHAR2
ERR_PASSWD EXCEPTION;
BEGIN
-- 암호화된 비밀번호를 복호화 함수 호출로 본래 비밀번호 얻는다.
SELECT PACK_ENCRYPTION_DECRYPTION.FUNC_DECRYPT(PASSWD)
INTO V_PASSWD_OUTPUT
FROM TBL_NEWMEMBER
WHERE ID = V_ID;
IF V_PASSWD_INPUT != V_PASSWD_OUTPUT THEN
RAISE ERR_PASSWD;
ELSE
DBMS_OUTPUT.PUT_LINE( '로그인 성공^^');
END IF;
EXCEPTION
WHEN ERR_PASSWD THEN
RAISE_APPLICATION_ERROR(-20010, 'ㅜㅜ암호가 틀립니다.ㅜㅜ');
END;
[ 실행화면 ]
[ 실행결과 ]
EXEC PCD_LOGINCK('KIMTWOGYO', 'ABCD');