비밀번호 암호화/복호화

조수경·2022년 2월 11일
0

Spring

목록 보기
24/43
CREATE OR REPLACE PACKAGE BODY PKG_GET_NM
IS
    --첫번째 함수 BODY
    FUNCTION FN_MEMNAME(P_EMP_NUM IN VARCHAR2) RETURN VARCHAR2
    IS
    --SCALAR변수
        R_NM VARCHAR2(100); 
    BEGIN
        --PL/SQL에서의 SELECT에는 꼭 INTO문이 있어야 함
        SELECT NM INTO R_NM
        FROM   EMP
        WHERE  EMP_NUM = P_EMP_NUM;

        DBMS_OUTPUT.PUT_LINE('생성 완료!');

        RETURN R_NM;
    END FN_MEMNAME;

    --두번째 함수BODY
    FUNCTION FN_GET_CUS_NM(P_CAR_NUM IN VARCHAR2) RETURN VARCHAR2
    IS
        R_CUS_NM CUS.CUS_NM%TYPE;
    BEGIN
        SELECT B.CUS_NM INTO R_CUS_NM
        FROM   CAR A INNER JOIN CUS B ON(A.CUS_NUM = B.CUS_NUM)
        WHERE  A.CAR_NUM = P_CAR_NUM;

        RETURN R_CUS_NM;
    END FN_GET_CUS_NM;
END PKG_GET_NM;
/
SELECT CAR_NUM, MK, PY, DRI_DIST, PKG_GET_NM.FN_GET_CUS_NM(CAR_NUM) CUS_NM FROM CAR;

--오라클 자료형(데이터 타입)
/*
https://technet.tmaxsoft.com/upload/download/online/tibero/pver-20150504-000001/tibero_pkg/chap_dbms_obfuscation.html
* RAW
 - 2000Byte까지 저장
 - 이진(Binary : 0 1)데이터 저장
 - 문자형 -> 이진데이터로 저장 : STRING_TO_RAW
 - 이진데이터 -> 문자형으로 읽을때 : RAW_TO_CHAR

* DBMS_CRYPTO 
 - 암호화/복호화 패키지
 - 오라클 10g 이상에서 지원
 - 해시 알고리즘 제공 : 임의의 길이의 데이터를 고정길이의 해시값으로 변환
 - 데이터의 암호화 및 복호화를 위해 DES, AES 등의 다양한 알고리즘 지원

* DBMS_OBFUSCATION_TOOLKIT
 - 데이터를 암호화하고 복호화 하는 패키지.
 - 암호화 : 1234 -> ASLDFKJHSDAHFSIA
 - 복호화 : ASLDFKJHSDAHFSIA -> 1234

* 대칭키 = 비밀키 = 관용키
 - DES, IDEA, SKIPJACK 등
 - 암호화와 복호화를 동일한 키를 사용 <-> 암호화와 복호화 시 서로 다른 키를 사용하는 것은 비대칭키(공개키)
 - 보안이 뚫리면 끝
*/
--1. 선언부
CREATE OR REPLACE PACKAGE PKG_CRYPTO
IS
    --암호화 함수 정의
    FUNCTION ENCRYPT(INPUT_STRING IN VARCHAR2) RETURN RAW;
    --복호화 함수 정의
    FUNCTION DECRYPT(INPUT_STRING IN VARCHAR2) RETURN VARCHAR2;
END PKG_CRYPTO;
/
--2. 구현부
CREATE OR REPLACE PACKAGE BODY PKG_CRYPTO
IS
    --암호화 함수 구현
    FUNCTION ENCRYPT(INPUT_STRING IN VARCHAR2) RETURN RAW
    IS
        CONVERTED_RAW RAW(64);
        KEY_DATA_RAW RAW(64);
        ENCRYPTED_RAW RAW(64);
    BEGIN
        --대상 데이터 암호화
        CONVERTED_RAW := UTL_I18N.STRING_TO_RAW(INPUT_STRING, 'AL32UTF8');
        --비공개키 암호화
        KEY_DATA_RAW := UTL_I18N.STRING_TO_RAW('12345678', 'AL32UTF8');

        ENCRYPTED_RAW := DBMS_CRYPTO.ENCRYPT(SRC=>CONVERTED_RAW
            ,TYP=>DBMS_CRYPTO.DES_CBC_PKCS5
            ,KEY=>KEY_DATA_RAW
            ,IV=>NULL
            );
        RETURN ENCRYPTED_RAW;
    END ENCRYPT;

    --복호화 함수 구현
    FUNCTION DECRYPT(INPUT_STRING IN VARCHAR2) RETURN VARCHAR2
    IS
        KEY_DATA_RAW RAW(64);
        DECRYPTED_RAW VARCHAR2(64); --RAW형의 VARCHAR2
        CONVERTED_STRING VARCHAR2(64); --VARCHAR2
    BEGIN
        --INPUT_STRING (IN)바인드 변수는 이미 이진데이터형이므로 STRING_TO_RAW를 할 필요가 없음
        --비공개키 암호화(대칭키이므로 동일함)
        KEY_DATA_RAW := UTL_I18N.STRING_TO_RAW('12345678', 'AL32UTF8');
        --DECRYPT : RAW(이진데이터) -> STRING(문자데이터)
        DECRYPTED_RAW := DBMS_CRYPTO.DECRYPT(SRC=>INPUT_STRING
                    ,TYP=>DBMS_CRYPTO.DES_CBC_PKCS5
                    ,KEY=>KEY_DATA_RAW
                    ,IV=>NULL);
        --DBMS_CRYPTO.DECRYPT 결과(복호화) 의 RAW 데이터를 VARCHAR2로 변환
        CONVERTED_STRING := UTL_I18N.RAW_TO_CHAR(DECRYPTED_RAW, 'AL32UTF8');
        RETURN CONVERTED_STRING;
    END DECRYPT;
END PKG_CRYPTO;
/
--선언부
CREATE OR REPLACE PACKAGE PKG_CRYPTO
IS
    FUNCTION ENCRYPT(INPUT_STRING IN VARCHAR2) RETURN RAW;
    FUNCTION DECRYPT(INPUT_STRING IN VARCHAR2) RETURN VARCHAR2;
END PKG_CRYPTO;
/
CREATE OR REPLACE PACKAGE BODY PKG_CRYPTO
IS
    FUNCTION ENCRYPT(INPUT_STRING IN VARCHAR2) RETURN RAW
    IS
        CONVERTED_RAW RAW(64);
        KEY_DATA_RAW  RAW(64);
        ENCRYPTED_RAW RAW(64);
    BEGIN
        --암호화X, 문자를 RAW(바이너리)로 변환
        CONVERTED_RAW := UTL_I18N.STRING_TO_RAW(INPUT_STRING,'AL32UTF8');
        KEY_DATA_RAW := UTL_I18N.STRING_TO_RAW('12345678','AL32UTF8');
        --암호화o
        ENCRYPTED_RAW := DBMS_CRYPTO.ENCRYPT(
            SRC=>CONVERTED_RAW
            ,TYP=>DBMS_CRYPTO.DES_CBC_PKCS5
            ,KEY=>KEY_DATA_RAW
            ,IV=>NULL
        );
        RETURN ENCRYPTED_RAW;
    END ENCRYPT;

    FUNCTION DECRYPT(INPUT_STRING IN VARCHAR2) RETURN VARCHAR2
    IS
        --64RAW : 64Byte(512bit)
        KEY_DATA_RAW RAW(64);
        DECRYPTED_RAW RAW(64);
        CONVERTED_STRING VARCHAR2(64);
    BEGIN
        KEY_DATA_RAW := UTL_I18N.STRING_TO_RAW('12345678','AL32UTF8');
        --복호화o => RAW(바이너리)
        DECRYPTED_RAW := DBMS_CRYPTO.DECRYPT(
            SRC=>INPUT_STRING
            ,TYP=>DBMS_CRYPTO.DES_CBC_PKCS5
            ,KEY=>KEY_DATA_RAW
            ,IV=>NULL
        );
        --RAW->VARCHAR2
        CONVERTED_STRING := UTL_I18N.RAW_TO_CHAR(DECRYPTED_RAW,'AL32UTF8');
        RETURN CONVERTED_STRING;
    END DECRYPT;
END PKG_CRYPTO;
/

SELECT PKG_CRYPTO.ENCRYPT('test') FROM DUAL;
SELECT PKG_CRYPTO.DECRYPT('A04B686B118AF67B') FROM DUAL;

SELECT *
FROM MEMBER;

--MEMBER 테이블의 PASSWORD 컬럼의 데이터를 암호화
--상관관계 서브쿼리 + EXISTS UPDATE로 처리
UPDATE MEMBER A
SET A.PASSWORD =  (
    SELECT  PKG_CRYPTO.ENCRYPT(B.PASSWORD)--암호화된 password
    FROM MEMBER B
    WHERE B.MEMBERID = A.MEMBERID --**********
);
COMMIT;

--아이디, 비밀번호 인증
SELECT * FROM MEMBER
WHERE MEMBERID = 'a001'
AND PASSWORD = PKG_CRYPTO.ENCRYPT('asdfasdf');

SELECT PKG_CRYPTO.DECRYPT('04FC1AD4078C4BE0158F4B2AA46FF591') FROM DUAL;

암호화 완료!!

profile
신입 개발자 입니다!!!

0개의 댓글