-
[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