PostgreSQL에서는 pgcrypto 모듈에서 패스워드 암호화를 위한 함수인 crypto()와 gen_salt(n)를 제공한다
crypto() 함수는 해시 작업, gen_salt() 함수는 솔트값을 생성할 암호화 알고리즘을 지정하는 함수이다.
해당 함수로 만든 패스워드는 복호화가 불가하다. 따라서 나중에 패스워드 검증을 위해서는 복호화가 아닌 암호화를 한 후 비교해야 한다는 특징이 있다.
crypto 함수에서 제공하는 암호화 알고리즘은 다음과 같다.
알고리즘 | 평문 최대 길이 | salt 길이 | 출력 길이 | 비고 |
bf | 72 | 128 | 60 | Blowfish |
md5 | X | 48 | 34 | MD5 |
des | 8 | 12 | 13 | UNIX의 암호화 방식 |
xdes | 8 | 24 | 20 | 확장 DES |
이제 사용법을 알아보자!
아래 쿼리를 사용하여 pgcrypto 플러그인을 설치하면 준비는 끝난다.
CREATE EXTENSION pgcrypto;
이후 다음과 같이 사용하면 된다.
// DB INSERT
INSERT INTO db_table(id, password) VALUES('entered id', crypt('entered password', gen_salt('md5')));
// DB UPDATE
UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
// 비밀번호 검증
SELECT id
FROM db_table
WHERE password = crypt('entered password', password);
pgcrypt에서는 복호화가 되는 암호화 함수도 지원한다.
대칭키를 이용하는 함수인 pgp_sym_encrypt() / pgp_sym_decrypt()와, 비대칭키(공개키)를 이용하는 함수인 pgp_pub_encrypt() / pgp_pub_decrypt()가 있다.
위 함수는 다음과 같이 사용하면 된다.
참고로 대칭키의 key는 text, 공개키의 key는 bytea 자료형을 요구하므로 사용에 주의하자!
// 공개키로 암호화
SELECT pgp_pub_encrypt('entered msg', key);
SELECT pgp_pub_encrypt_bytea('entered bytea msg', key);
// 공개키로 암호화된 문자열 복호화
SELECT pgp_pub_decrypt('encrypted msg', key);
SELECT pgp_pub_decrypt_bytea('encrypted bytea msg', key);
// 대칭키로 암호화
SELECT pgp_sym_encrypt('entered msg', key);
SELECT pgp_sym_encrypt_bytea('entered bytea msg', key);
// 대칭키로 암호화된 문자열 복호화
SELECT pgp_sym_decrypt('encrypted msg', key);
SELECT pgp_sym_decrypt_bytea('encrypted bytea msg', key);
암호화에 사용된 키를 통해 어떤 방식으로 암호화 되었는지 알아낼 수 있는 함수인 pgp_key_id()도 제공한다.
이 함수는 'SYNKEY' 혹은 'ANYKEY' 값을 반환한다.
SELECT pgp_key_id(key);
비밀번호 외에도 일반 문자열 암호화를 위한 encrypt() / decrypt() 함수도 있다.
이 함수는 key 외에도 세 번째 인자로 암호화 알고리즘을 가리키는 type을 요구하는데, type의 값은 다음과 같은 형식으로 이루어진다.
알고리즘 [ -모드 ] [ /pad: 패딩 ]
알고리즘으로는 bf, aes, des 등을 사용할 수 있다.
모드는 cbc, ecb 둘 중 하나를 사용할 수 있으며, 기본값은 cbc이다.
- cbc: 이전 블록에 따라 다음 블록이 정해짐
- ecb: 각 블록이 독립적으로 암호화
패딩은 pkcs, none 둘 중 하나를 사용할 수 있으며, 기본값은 pkcs이다.
- pkcs: 가변길이 데이터
- none: 자료는 암호 블록의 배수 크기여야 함
아래와 같이 사용하면 된다!
// 암호화
SELECT encode(
encrypt(
convert_to('암호화할 문자열', 'utf8'), 'encrypt_key', 'aes'
), 'hex');
// 복호화
SELECT convert_from(
decrypt(
decode('위 방식으로 암호화된 hex 문자열', 'hex'), 'encrypt_key', 'aes'
), 'utf8');
encrypt와 decrypt 함수는 convert_to() / convert_from() 함수와 주로 함께 사용한다.
convert_to()
- 문자열 인코딩 함수
convert_from()
- 문자열 디코딩 함수
일반적인 해시 함수로는 digest()와 hmac() 함수를 지원한다.
digest(data, type)
입력한 data 값의 해시 이진값을 구하는 함수
digest() 함수의 결과값을 복호화하려면 encode() 함수를 사용하면 16진수 문자열로 변환할 수 있다.
select encode(digest('나는 미정', 'md5'), 'hex');
hmac(data, key, type)
입력한 data 값과 key값을 사용하여 MAC 해시 값을 구하는 함수
HMAC(Hash-based Message Authentication Code)이란?
메시지 변조 여부를 확인할 수 있는 해시 기반 MAC
그 외, 랜덤한 문자열을 생성해 주는 함수로 gen_random_uuid()와 gen_random_bytes(n)가 있다.
gen_random_uuid()는 아래와 같은 UUID를 반환하는 함수이다.
gen_random_bytes()의 경우에는 자연수 n을 매개변수로 받고, bytea 결과값을 반환한다.
다음과 같이 사용하면 된다.
SELECT gen_random_bytes(2);
SELECT gen_random_uuid();
'Backend > Database' 카테고리의 다른 글
Database - ORDER BY 커스텀 정렬 (0) | 2021.09.14 |
---|---|
Database - 문자열 포함 여부 (0) | 2021.05.16 |
Database - 널(NULL)값 처리 (0) | 2021.05.16 |
Database - 날짜 포맷팅 (0) | 2021.05.16 |
PostgreSQL - 현재 시퀀스 값 변경 (0) | 2021.05.03 |