Backend/Database

PostgreSQL - pgcrypto 모듈을 사용한 패스워드 및 문자열 암호화

둉이 2021. 12. 3. 04:13

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