리코딩 : TIL

bcrypt로 비밀번호를 만들고 저장!

BreezeBm 2021. 10. 2. 19:04

1. bcrpyt란?

A library to help you hash passwords (출처 : https://www.npmjs.com/package/bcrypt)

 bcrpyt npm 사이트에 한줄로 알잘딱깔쎈으로 정리 되어있다. 말 그대로 암호 해싱을 도와주는 라이브러리이다. 암호를 해싱하는 것은 중요하다. 내가 만약 회원가입 로직을 작성하는 파트를 담당했다. 유저가 암호를 입력하고 회원가입을 눌렀을 때, 데이터베이스에 저장이된다. 이때 데이터 베이스에 유저의 암호가 태초의 모습, 날것 그대로 들어가게 된다. 악의적인 누군가에 데이터베이스를 털리게 되면 개인 정보와 함께 비밀번호도 같이 털리고, 비밀번호는 보통... 대부분 사이트에서.. 비슷...비슷 하니까... 난리난리.. 나도 상사한테 털리고.... 또한 꼭 해커나 악의적인 유저가 아닌 회사에서 선량한척 일하고 있지만 뒷돈을 받고 정보를 팔 수도 있으니까.... 중요한 사실은 보안성 강화를 위해 반드시 비밀번호는 암호화가 되어야 한다!

 

2. bcrypt 설치

npm install bcrpyt 

3. bcrpyt 사용하기

const bcrpyt = require("bcrypt");

 라이브러리를 사용할 곳에 불러 온다. 다음 코드는 npm bcrypt에서 튜토리얼처럼 보여 주고 있는 코드이다.

 - async 

다음 코드는 bcrpyt npm 페이지에서 튜토리얼 코드처럼 작성되어 있었다. 

bcrypt.genSalt(saltRounds, function(err, salt) {
    bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
        // Store hash in your password DB.
    });
});

bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
    // Store hash in your password DB.
});

이코드를 활용해서 아래와 같이 작성했다.

app.post("/signup", async (req, res) => {
  let { pswd, name } = req.body;
  const saltRounds = 10;
  try {
    bcrypt.genSalt(saltRounds, function (err, salt) {
      bcrypt.hash(pswd, salt, async function (err, hash) {
        await userModel.create({ name, pwd: hash });
        res.status(200).send({ message: `${hash}` });
      });
    });
  } catch (err) {
    console.error(err);
  }
});

우선 바디에 비밀번호를 보내준다. 비밀번호를 받아서 salt를 생성하고, 비밀번호와 생성된 salt로 비밀번호를 해싱한다. 그래고, 유저를 만들어준다. 응답으로 비밀번호를 보내달라고 했는데(실전에서 그러면 안됩니다...), 어떻게 찍히나 보고 싶어서 했습니다..!

$2b$10$2NiBe1Rm4TX1PEHqXixZT.mkGgNj7sn9gDkXlr8V2kJQjA/qeaZQ.

이렇게 알수 없는 문자열을 응답을 받았다.

 

우선 해시 함수는 같은 입력값에 대해 언제나 동일한 해시를 출력한다. 그렇기 때문에 미리 해시 값을을 계산해 놓은 레이보우 테이블을 가지고 있는 악의적인 유저가 있으면 해시 함수의 반환 값을 역으로 추적해서 원래의 비밀번호를 쉽게 찾을 수 있다. 그것을 방지하기 위해서 bcrypt에서는 salt를 생성하는 함수와 saltRounds를 설정할 수 있다.

 

salt는 유저가 보낸 비밀번호 데이터 외에 추가적으로 무작위 데이터를 더해서 해시값을 계산하는 방법이다. salt는 소금을 뜻하는데, 요리에 양념을 치듯이 비밀번호에 추가적으로 양념(?)을 치는것과 같다. (이름 너무 찰떡... 소금이라니..) saltRounds는 소금을 치는 횟수 일수도 있지만,  기존에 salt를 적용해서 나온 결과에 다시 동일한 salt를 적용해서 해시를 도출하는 그 횟수를 말한다. 그래서 횟수가 높아 질 때마다 시간이 오래 걸리는 것을 확인할 수 있다!

 

자 이제 회원가입을 bcrpyt를 통해 진행을 했다. 그렇다면 로그인을 할때는 어떻게 해야할까? 이것 역시도 bcrypt가 제공해주고 있다.

// hash는 데이터베이스에 저장되어 있는 비밀번호
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
    // result == true
});
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, result) {
    // result == false
});

튜토리얼에 나와있는 코드이다. compare라는 함수를 통해서 바디로 보내준 비밀번호를 디비에 저장이 되어있던 해쉬된 비밀번호와 비교해서 일치하면 true, 틀리면 false를 반환해준다. 

 

공부공부...