될때까지

비밀번호 암호화 bcrypt 본문

카테고리 없음

비밀번호 암호화 bcrypt

랖니 2022. 8. 21. 12:33
728x90

bcrypt란?

사용자의 비밀번호를 데이터베이스에 그대로 저장하면 보안법에 어긋난다. 절대 안됨!! 그래서 입력된 데이터를 변형시켜 암호화하는 단방향 해시함수 중 하나다. salting(실제 데이터 이외에 무작위 데이터를 넣어서 해시값을 만드는 방법)과 키 스트레칭(해시된 값을 또 해시하고 반복하는 방법)으로 보안성을 강화했다.

단방향은 외부 해킹에 의한 데이터 노출뿐만 아니라 내부에서도 데이터 유출을 방지할 수 있기에 보안성이 더 뛰어나다.

 

node에서 bcrypt 사용해서 암호화하기

먼저 bcrypt모듈을 설치한다.

npm install bcrypt

 

그리고 bcrypt모듈을 사용할 파일에서 불러온다. 어디서 bcrypt를 사용해 비밀번호를 암호화 해야할까? controller에서는 req, res를 받아 데이터를 검증한다고 배웠다. 그리고 service에서 실제적인 비즈니스 로직을 작성한다 알고있기에 나는 service에서 bcrypt를 불러왔다.

// services > userService.js

const userDao = require("../models/userDao");
const bcrypt = require("bcrypt");

const signUp = async (username, password) => {
    const pwValidation = new RegExp(
        '^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,20})'
    );

    if (!pwValidation.test(password)) {
        const err  = new Error("PASSWORD_IS_NOT_VALID");
        err.status = 400;
        throw err;
    }

    await userDao.createUser(
        username,
        hashedPassword
    );
}

password에는 사용자로부터 입력받은 비밀번호가 저장되어있다. 이를 bcrypt를 사용해 암호화하기 위해선 아래와 같이 적어주면 된다.

    const hashedPassword = await bcrypt.hash(password, 10);

bcrypt의 hash메소드를 사용할 때 첫번째 인자로 password를 전달하고 두번째 인자로 10을 적용했다. 이 10은 salt로 암호화에 사용할 소금치는 작업을 몇번 진행할지를 뜻한다. 보통 10으로 설정하는데 이 숫자가 높을수록 암호화가 강력해지지만 속도가 느려진다는 점에 유의할 것!!

포스트맨을 이용해 회원가입을 진행해보자

회원가입 성공

mysql workbench에서 회원가입된 정호를 조회해보면 비밀번호가 암호화되서 예쁘게 들어간 걸 확인할 수 있다.😝

암호화 성공

 

비밀번호 검증하기

    const checkedPassword = await bcrypt.compare(password, userInfo.password);

bcrypt.compare() 메소드를 사용해서 입력된 데이터와 저장된 암호화값을 비교하면 비교결과가 true, false로 리턴된다. 이를 checkedPassword변수에 저장하여 판별하는 로직을 추가하면 완성!

로그인에 작성한 코드는 아래와 같다.

const signIn = async (username, password) => {
    const [userInfo] = await userDao.getUserByUsername(username);

    if (!userInfo) {
        const err = new Error("USER_DOES_NOT_EXIST");
        err.status = 404;
        throw err;
    }
    
    const checkedPassword = await bcrypt.compare(password, userInfo.password);
    //console.log('checkedPassword', checkedPassword)    일치하면 true 다르면 false를 출력한다

    if (!checkedPassword) {
        throw { status : 404, message : "PASSWORD_DOES_NOT_MATCH" }
    }

    // 로그인에 성공했다면? 토큰 보내줘야함
}

 

 

 

 

https://www.npmjs.com/package/bcrypt

728x90