본문 바로가기
프로그래밍 언어/TypeScript

[TypeScript] Bcrypt를 이용한 비밀번호 해쉬화(암호화)

by BK0625 2023. 12. 15.
반응형

회원가입을 할 때 데이터베이스에 비밀번호 같이 보안에 민감한 정보를 그냥 저장하면 안되고 암호화해서 저장하는게 안전하다.
 
node.js에서는 주로 Bcrypt를 사용해서 비밀번호 해쉬화를 해 저장한다.
 
해쉬화는 단방향으로 해쉬 알고리즘을 이용하여 비밀번호를 암호화시키며 당연히 단방향이라 복구는 불가능하다. 다시 말하면 한쪽 방향으로만 암호화를 하는 단방향 암호화이기 때문에 암호화는 가능하지만 복호화는 불가능하다.
 
기존 해시 함수에서는 무차별 대입 공격(고성능 GPU를 이용해 무차별적으로 해시함수를 대입해 같은 digest를 찾는 공격)에 취약했는데 bcrypt는 salting 방식을 통합하여 취약점을 보완했다. 임의의 salt 값을 덧붙여 hash 함수를 진행하기 때문에 같은 비밀번호여도 다른 digest 값을 발생시켜 digest 값끼리 비교하기 어렵게 한다.

 

사용법

 
먼저 bcrypt를 설치한다.
 

npm install bcrypt
# 타입스크립트(typescript) 사용할 경우
npm install -D @types/bcrypt

 
 
그런 다음 비밀번호 암호화를 진행한다.
 

 async hashing(userPw:string){    
        const saltRound = 10; //암호화 연산에 사용되는 salt의 cost, 높을수록 암호화 연산이 증가하는 대신 속도가 느려짐
        const salt = await bcrypt.genSalt(saltRound);

        const hashedPassword = await bcrypt.hash(userPw,salt); //비밀번호 해쉬화

        return hashedPassword; //해쉬화한 비밀번호를 데이터베이스에 저장
    }

 
 
먼저 saltRound를 정해주는데 이는 암호화 연산에 사용되는 salt의 cost이다. salt는 공격자가 암호를 유추할 수 없도록 평문 데이터에 의미 없는 데이터를 뿌려 넣는 것을 말한다. 높을수록 암호화 연산은 증가하지만 속도가 느려지게 된다. getSalt  메소드로 소금을 생성하고 hash 함수에 비밀번호와 salt를 넣어 해쉬화를 시킨다. 이 해쉬화된 비밀번호를 데이터베이스에 저장하면 된다. 저장할 때 해쉬화된 비밀번호가 길어서 에러가 발생할 수 있으니 해당 컬럼의 length를 넉넉히 주자.
 
 

비밀번호 검증

  /**유저 로그인 */
    async login() {
        const user:user = this.body;
        const res = await prisma.user.findFirst({
            where:{
                userId:user.userId
            }
        });
        if(res?.userId==null || res.userPw==null){
            return {success:false,status:404}
        }
        const check = await bcrypt.compare(user.userPw,res?.userPw);

        if(check) return {success:true,status:201}; //로그인 성공
        else return {success:false, status:400}; //로그인 실패
        
    }

 
 
사용자가 로그인 할 때 입력 받은 비밀번호와 데이터베이스에 저장된 해쉬화된 비밀번호를 비교하여 true가 나오면 로그인을 성공시킨다.
 
 
공부하면서 정리한 내용입니다. 모든 지적 감사히 받겠습니다:)

반응형