ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Postgresql] 데이터 해시화, 암호화, 복호화
    DB/PostgreSQL 2021. 4. 3. 22:41

    해시화

    MD5

    md5 는 해시화로 한번 변형을 하면 복원을 할 수 없습니다. 예전에는 비밀번호와 같은 값을 많이 변환했지만 보안적인 측면에서 이미 취약하다고 하기 때문에 탈취가 되어도 크게 중요하지 않은 데이터에서만 사용하기를 권장합니다.

    형식

    md5(문자열) return hex

    예시

    SELECT md5('abcd');
    -- e2fc714c4727ee9395f324cd2e7f331f

    digest

    digest를 사용하면 md5 뿐만 아니라 sha1, sha256, sha512와 같이 평문을 해시화 할 수 있습니다. 반환 타입은 bytea 이므로 encode()함수를 사용해 16진수로 변환하여 사용하면 됩니다.

    형식

    해시 타입
    md5, sha1, sha224, sha256, sha384, sha512
    
    digest(문자열, 해시타입) return bytea

    예시

    select digest('abcd', 'md5');
    -- E'\\xE2FC714C4727EE9395F324CD2E7F331F'
    
    select encode(digest('abcd', 'md5'), 'hex');
    -- e2fc714c4727ee9395f324cd2e7f331f
    
    select encode(digest('abcd', 'sha256'), 'hex');
    -- 88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589

    암복호화

    Postgresql에서 데이터 암복호화를 하기 위해서는 extension을 설치해야 합니다.

    CREATE EXTENSION pgcrypto;

    암호화와 복호화는 순서가 반대입니다. 암호화가 1 → 2 → 3 이 순으로 진행이 되었다면 복호화는 3 → 2 → 1 순으로 진행돼야 합니다.

    암호화

    convert_to

    보통은 아래와 같이 변환을 하지 않아도 되지만 어느 데이터가 들어올 지 예상이 되지 않을 땐 사용하는 것이 안전합니다.

    형식

    convert_to('문자열', 인코딩) return bytea - utf8 범위 안에서 표현됨

    예시

    select convert_from('abcd', 'utf8')
    -- abcd
    
    select convert_to('abcd', 'utf8')
    -- abcd

    encrypt

    encrypt는 bytea 타입으로 리턴이 되므로 encode 함수를 사용해 16진수로 변경하여 사용합니다.

    형식

    암호화 방식
    blowfish = bf
    rijndael = aes -
    des      = des - 56비트로 키 길이가 짧아서 보안에 취약
    3des     = 3des - des를 3번 반복한 것으로 잘 안씀
    
    암호화 모드
    cbc — 가장 많이 사용 (기본값)
    ecb — 보안에 취약
    
    패딩
    pkcs — 가변 길이 자료 (기본값)
    none — 자료는 암호 블록의 배수 크기여야 함
    
    encrypt(암호화할 문자열, 암호키, 암호화 방식-암호화 모드/pad:패딩) return bytea

    예시

    select encrypt('abcd', 'key','aes');
    -- E'\\xF0C769069D2BAF4A05966F7C0B46E173'
    
    select encrypt('abcd', 'key','aes-ecb/pad:none');
    -- E'\\x046EA9A26F7D7C9DC7C8F5CED5FEE132'
    
    select encrypt(convert_to('abcd', 'utf8'), 'key','aes');
    -- E'\\xF0C769069D2BAF4A05966F7C0B46E173'

    encode

    bytea 타입으로 나온 결과를 입력된 타입으로 변경합니다.

    형식

    지원 타입
    base64, hex, escape
    
    형식
    encode(bytea 타입 데이터, 지원타입) return text

    예시

    select encode('123\000456'::bytea, 'escape')
    -- 123\000456
    
    select encode(encrypt(convert_to('abcd', 'utf8'), 'key','aes'), 'hex');
    -- f0c769069d2baf4a05966f7c0b46e173
    
    select encode(encrypt(convert_to('abcd', 'utf8'), 'key','aes'), 'base64');
    -- 8MdpBp0rr0oFlm98C0bhcw==

    armor

    ASCII-armor(PGP;Pretty Good Privacy) 형식으로 변환합니다. ASCII-armor란 바이너리를 텍스트로 인코딩하는 컨버터로 암호화된 결과를 ASCII로 묶어 이메일과 같은 표준 메시징 형식으로 보낼 수 있습니다. CRC 값을 가지는 Base64 인코딩 타입을 기본값으로 가집니다.

    형식

    armor(data bytea [ , keys text[], values text[] ]) returns text

    예시

    select armor('abcd'::bytea)
    -----BEGIN PGP MESSAGE-----
    
    YWJjZA==
    =S2Mq
    -----END PGP MESSAGE-----
    
    select armor(encrypt(convert_to('abcd', 'utf8'), 'key','aes'));
    -----BEGIN PGP MESSAGE-----
    
    8MdpBp0rr0oFlm98C0bhcw==
    =+v1Q
    -----END PGP MESSAGE-----

    복호화

    decrypt

    encrypt의 역순이라 생각하면 쉽습니다. 암호화 방식, 모드, 패딩 모두 동일합니다.

    형식

    복호화 방식
    blowfish = bf
    rijndael = aes -
    des      = des - 56비트로 키 길이가 짧아서 보안에 취약
    3des     = 3des - des를 3번 반복한 것으로 잘 안씀
    
    복호화 모드
    cbc — 가장 많이 사용 (기본값)
    ecb — 보안에 취약
    
    패딩
    pkcs — 가변 길이 자료 (기본값)
    none — 자료는 암호 블록의 배수 크기여야 함
    
    decrypt(복호화할 문자열, 암호키, 복호화 방식-복호화 모드/pad:패딩) return bytea

    예시

    with enc_table (enc_data) as (
        select encrypt('abcd', 'key','aes')
    )
    
    select decrypt(enc_data, 'key', 'aes')
    from enc_table
    -- abcd
    
    -- 키나 암호화 방식이 맞지 않으면 올바르게 복호화 되지 않음
    select decrypt(enc_data, 'key1', 'aes')
    from enc_table
    -- E'\\xEF1E3AC015A0DE4B91FAE0507E5A1193'
    
    select decrypt(enc_data, 'key', 'des')
    from enc_table
    -- E'\\xF0EC79F56DE25140FDEBB862D534C100'

    decode

    encode의 역순입니다. 타입은 encode와 동일하게 지원합니다.

    형식

    decode(text 타입 데이터, 지원타입) return bytea

    예시

    select decode('123\000456', 'escape');
    -- E'\\x31323300343536'
    
    with enc_table (enc_data) as (
        select encode(encrypt('abcd', 'key','aes'), 'hex')
    )
    
    select decrypt(decode(enc_data, 'hex'), 'key', 'aes')
    from enc_table;
    -- abcd

    convert_from

    형식

    convert_from('utf8 범위 안의 bytea 문자열', 인코딩) return text

    예시

    select convert_from('abcd', 'utf8')
    -- abcdwith enc_table (enc_data) as (
     select encode(encrypt(convert_to('abcd', 'utf8'), 'key','aes'), 'hex')
    )
    
    select convert_from(decrypt(decode(enc_data, 'hex'), 'key', 'aes'), 'utf8')
    from enc_table;

    dearmor

    형식

    dearmor(data text) returns bytea

    예시

    with enc_table (enc_data) as (
        select armor('abcd'::bytea)
    )
    
    select dearmor(enc_data)
    from enc_table;
    -- abcd
    
    with enc_table (enc_data) as (
        select armor(encrypt(convert_to('abcd', 'utf8'), 'key','aes'))
    )
    
    select convert_from(decrypt(dearmor(enc_data), 'key', 'aes'), 'utf8')
    from enc_table;
    -- abcd

    댓글