본문 바로가기
IT

[Postgresql] 패스워드 단방향 암호화 및 체크 함수

by 쪼이빠빠 2023. 5. 7.
728x90
반응형

웹서비스 로그인을 위한 패스워드 단방향 암호화를 Postgresql 데이터베이스 기반하에 구현하는 방법을 설명한다.

postgresql 패스워드 암호화


웹서비스를 구축하면서 로그인 기능은 가장 많이 구현하는 기능중 하나이다. 로그인을 하려면 사용자의 패스워드 정보를 단방향 암호화로 DB에 저장 해야 한다.
아래 코드는 패스워드를 단방향 암호화로 저장하고 체크하는 내용을 정리한 것이다.

우선, 테이블에 사용자 추가 시 패스워드를 암호화하여 insert 수행하는 Trigger 함수와 Trigger를 정의한다.

1. 사용자 패스워드 단방향 암호화 트리거 함수

CREATE OR REPLACE FUNCTION encrypt_pg_users_password()
RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'INSERT' OR (TG_OP = 'UPDATE' AND NEW.password <> OLD.password) THEN
    NEW.password = crypt(NEW.password, gen_salt('bf'));
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

[참고]
암호화 함수인 crypt() 함수는 주어진 패스워드를 지정된 salt를 사용해 해시 값으로 변환하는 PostgreSQL 내장 함수이다. 
crypt() 함수는 일반적으로 데이터베이스 사용자의 패스워드를 암호화하거나 데이터베이스에서 저장하는 다른 중요한 정보를 보호하기 위해 사용된다. 
crypt() 함수는 지정된 salt를 사용하여 주어진 문자열을 암호화하고 결과 해시 값을 반환한다다.

여기서 사용된 salt는 bf로, Blowfish 알고리즘을 사용한다. Blowfish는 1993년에 Bruce Schneier가 개발한 대칭키 블록 암호화 알고리즘 중 하나이다. 
Blowfish는 안전성과 속도가 모두 우수하다는 장점을 가지고 있어서, 다양한 분야에서 사용된다. 
bf salt를 사용하면 암호화된 패스워드를 보다 안전하게 보호할 수 있다.

암호화된 패스워드는 데이터베이스 내부에 저장되므로, 암호화된 패스워드를 가져와서 비교하는 것으로 사용자 인증을 수행할 수 있다. 
이를 위해 crypt() 함수를 사용하여 입력된 패스워드를 암호화하고, 저장된 암호화된 패스워드와 비교하는 것으로 패스워드 검증을 수행할 수 있다.


2. 사용자 정보 테이블 패스워드 INSERT, UPDATE 트리거

-- INSERT Trigger
CREATE TRIGGER encrypt_pg_users_inst_password_trigger
BEFORE UPDATE ON pgportal.pg_users
FOR EACH row
EXECUTE FUNCTION encrypt_pg_users_password();

--  UPDATE Trigger
CREATE TRIGGER encrypt_pg_users_upt_password_trigger
BEFORE UPDATE ON pgportal.pg_users
FOR EACH row
EXECUTE FUNCTION encrypt_pg_users_password();

 

위의 함수는 `bf` 알고리즘을 이용해 입력된 패스워드를 암호화하고, Trigger는 해당 함수를 UPDATE 이벤트 발생 전에 실행하여 새로운 패스워드가 입력되거나 업데이트 되었을 때 암호화된 패스워드를 저장하도록 한다.

다음으로, 아래의 코드는 패스워드 체크를 위한 함수를 정의한 것이다.

3. 패스워드 체크 함수

CREATE OR REPLACE FUNCTION pgportal.check_password(p_id VARCHAR, p_password VARCHAR)
RETURNS BOOLEAN AS $$
DECLARE
  v_password_digest CHAR(60);
BEGIN
  -- 사용자의 Password를 가져옴
  SELECT PASSWORD INTO v_password_digest
  FROM pgportal.pg_users
  WHERE id = p_id;

  -- 사용자가 없거나 비밀번호가 일치하지 않으면 FALSE 반환
  IF v_password_digest IS NULL OR NOT crypt(p_password, v_password_digest) = v_password_digest THEN
    RETURN FALSE;
  END IF;

  RETURN TRUE;
END;
$$ LANGUAGE plpgsql;

 

위의 함수는 입력된 사용자 ID와 패스워드를 이용해 암호화된 패스워드를 가져오고, 입력된 패스워드를 암호화하여 가져온 패스워드와 일치하는지 검사하여 결과를 반환한다.

이렇게 구현된 SQL 쿼리를 사용하면 데이터베이스에 저장되는 사용자 패스워드가 암호화되어 저장되므로, 보안에 더욱 안전하게 사용할 수 있다.


4. 함수 테스트

SELECT pgportal.check_password('test01','101010101');

 

반응형

 

반응형

댓글