bcryptjs 를 사용해보자

권태형·2023년 3월 11일

U-eat

목록 보기
5/7
post-thumbnail

U-eat프로젝트에서 회원정보관리르 맡아 비밀번호의 암호화 처리를 할 필요성이 발생했다. 따라서 hash처리를 할 때 쓸 수 있는 라이브러리를 찾았는데 그게 bcryptjs다. 따지면 bcrypt도 있었지만, bcrypt는 C++기반의 라이브러리로 동작시 js로 변환하는 작업을 거친다고 하는데 bcryptjs는 javascript만을 위한 라이브러리라고 설명되어 이 라이브러리를 쓰게 되었다.

bcryptjs는 뭘까?

bcryptjs는 해시 함수 라이브러리 중 하나로, 비밀번호와 같은 중요한 데이터를 안전하게 저장하기 위해 사용된다. bcryptjs는 JavaScript로 작성된 라이브러리이며, 데이터를 암호화하여 암호화된 데이터의 재생성을 어렵게 만든다.

우리는 일반적인 사이트에서 회원가입을 진행하고 비밀번호를 잃어버렸을 때 "비밀번호 찾기"가 아닌 "비밀번호 재설정"을 하게 된다. 이는 "단방향성 암호화처리"에 의해 관리자 조차 기존의 비밀번호를 복구할 수 없다. 위의 bcryptjs또한 "단방향성 암호화처리"를 기반으로 하기 때문에 암호화된 데이터의 재생성을 어렵게 만들 수 있다.

동작 원리

bcryptjs는 비밀번호를 암호화하는 과정을 "해싱(hashing)"이라고 한다. 이러한 해싱처리 기능은 내부적으로 "솔트(salt)"라는 추가적인 무작위 문자열을 사용하여 비밀번호를 보호한다. 이 솔트는 암호화된 비밀번호와 함께 저장되며, 이를 통해 각 비밀번호에 대한 고유한 해싱처리 된 값을 생성한다.

bcryptjs는 기본적으로 "10 라운드(round)"의 해싱을 사용한다. 이는 해시 함수가 2의 10승(약 1000) 번 이상 실행된다는 것을 의미한다. 이로 인해 암호화 된 비밀번호를 복호화하려는 공격자가 매우 많은 시간과 노력을 필요로 하기 때문에 보안성이 높아진다.

사용방법

bcryptjs는 npm을 통해서 간단하게 설치가 가능하다

npm install bcryptjs

사용할 코드에서 bcryptjs를 가져와서 비밀번호를 암호화하고 검증할 수 있다.
필자가 작성한 코드로 예시를 들면 아래는 bcryptjs로 비밀번호를 해싱처리해서 저장하는 회원가입과
해싱처리된 비밀번호를 검증하여 통화시키는 로그인의 API이다

const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');

 //회원가입
  register = async (userInfo) => {
    const { email, nickname, password } =
      await registerRequestPattern.validateAsync(userInfo);
    const isExistUser = await this.authRepository.getUserByEmailOrNickname({
      email,
      nickname,
    });
    if (isExistUser[0]) throw new ApiError('중복된 이메일 또는 닉네임', 400);
    
    const encryptedPassword = await bcrypt.hash(password, 10);
    
    await this.authRepository.register({ email, nickname, encryptedPassword });
  };

  //로그인
  userLogin = async (loginInfo) => {
    const { email, password } = await loginRequestPattern.validateAsync(
      loginInfo,
    );
    const [isExistUser] = await this.authRepository.getUserByEmail({ email });
    if (!isExistUser) throw new ApiError('이메일 또는 비밀번호 불일치', 401);
    const decipheredPassword = await bcrypt.compare(
      password,
      isExistUser.password,
    );
    if (decipheredPassword !== true)
      throw new ApiError('이메일 또는 비밀번호 불일치', 401);
    const token = await jwt.sign(
      { userId: isExistUser.userId },
      JWT_SECRET_KEY,
      {
        expiresIn: '1h',
      },
    );

    await loginResponsePattern.validateAsync(token);
    return { token, nickname: isExistUser.nickname };
  };

좀 더 간단한 예제나 자세한 사용방법을 확인하려면 bcryptjs github readme를 확인하자

특징

bcryptjs는 다음과 같은 특징을 가진다.

  • 솔트를 사용하여 암호화된 비밀번호를 안전하게 저장할 수 있습니다.
  • 해시 함수를 사용하여 보안성을 높일 수 있습니다.
  • 라운드(round) 기능을 제공하여 보안성을 높일 수 있습니다.
  • JavaScript로 작성되어 있기 때문에, Node.js와 함께 사용하기에 적합합니다.

장단점

bcryptjs는 솔트와 해시 함수를 사용하여 비밀번호를 안전하게 저장할 수 있기 때문에 아래와 같은 장단점을 가진다.

장점

  • 솔트와 해시 함수를 사용하여 보안성을 높일 수 있다.
  • Node.js와 함께 사용하기 쉽다.
  • 라이브러리를 사용하여 비밀번호 암호화와 검증 작업을 간단하게 처리할 수 있다.

단점

  • 높은 CPU 사용률로 인한 성능 문제가 발생할 수 있다.
  • 다른 암호화 라이브러리와 비교하여 처리 속도가 느릴 수 있다.

참고자료(출처)
12 - Bcryptjs - Cómo hacer hashing de una password. 유튜브 동영상
bcryptjs github readme
bcrypt의 작동원리와 노드에서 사용하는 방법

profile
22년 12월 개발을 시작한 신입 개발자 ‘권태형’입니다. 포스팅 하나하나 내가 다시보기 위해 쓰는 것이지만, 다른 분들에게도 도움이 되었으면 좋겠습니다. 💯컬러폰트가 잘 안보이실 경우 🌙다크모드를 이용해주세요.😀 지적과 참견은 언제나 환영합니다. 많은 댓글 부탁드립니다.

0개의 댓글