TIL 46 | 비밀번호 암호화 (Bcrypt & JWT)

dabin *.◟(ˊᗨˋ)◞.*·2021년 9월 24일
0

Node.js

목록 보기
9/11
post-thumbnail
post-custom-banner
//설치
npm install bcryptjs

암호화 진행 과정

  1. 사용자 비밀번호 입력 (ex/111111)
  2. Salt 생성
  3. Hashing(ex/$2b$10~) : 암호화된 정보로 변환
  4. 암호화된 비밀번호를 DB에 저장

유저 확인 과정

  1. 사용자 비밀번호 입력 (ex/111111)
  2. 암호화된 정보로 변환
  3. DB에 저장된 값과 비교
  4. true or false

[사용방법] https://www.npmjs.com/package/bcrypt

//async (recommended)
const bcrypt = require('bcrypt'); //bcrypt module 로드
const saltRounds = 10; //남들이 비밀번호 모르게 하는 일종의 노이즈
//라운드 값을 올릴수록 공격자들은 더 많은 컴퓨팅 파워가 필요해져 시간이 많이 걸린다. 

const myPlaintextPassword = 's0/\/\P4$$w0rD'; //나의 비밀번호라고 가정
const someOtherPlaintextPassword = 'not_bacon'; //다르게 입력한 비밀번호


//Hashing

//Technique 1 (salt & hash 따로 호출):
bcrypt.genSalt(saltRounds, function(err, salt) {
  bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
    // hash(암호화된 비밀번호) DB에 저장
  });
});

//Technique 2 (auto-gen a salt and hash):
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
   // hash(암호화된 비밀번호) DB에 저장
});



// Checking password

// Load hash from DB.
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
    // result == true
});
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, result) {
    // result == false
});

//async & await 사용
async function checkUser(username, password) {
  //... fetch user from a db etc.
  const match = await bcrypt.compare(password, user.passwordHash);
  if(match) {
    //login
  }
  //...
}

//생활코딩
const express = require('express');
const router = express.Router();
const shortid = require('shortid');
const db = require('../lib/db');
const bcrypt = require('bcrypt')

//sign up
router.post('/signup', (req, res) => {
  const { email, pwd, pwd2, displayName } = request.body;
  if (pwd !== pwd2) {
    request.flash('error', 'Password must same!');
    response.redirect('/user/signup');
  }else {
    bcrypt.hash(pwd, 10, (err, hash) => {
      const user = {
        id: shortid.generate(),
        email: email,
        password: hash,
        displayName: displayName
      };
      db.get('users').push(user).write();
        request.login(user, (err) => {
        console.log('redirect');
        return response.redirect('/');
      })
    });
  }
});

//Checking password
const checkPassword = (email, password, done) => {
  console.log('LocalStrategy', email, password);
  const user = db.get('users').find({
    email: email
  }).value();
  if (user) {
	bcrypt.compare(password, user.password, (err,result) => {
      if(result){
        return done(null, user, {
          message: 'Welcome.'
        });
      }else {
        return done(null, false, {
          message: 'Password is not correct.'
        });
      }
    });
  }else {
    return done(null, false, {
      message: 'There is no email.'
    });
  }
}

실습

const makeHash = async (password) => {
  return await bcrypt.hash(password, 10)
}
, 
const main = async () => {
  const hashedPassword = await makeHash('1a1a');
  console.log(hashedPassword)
}

main()

---------------------------------------------------

import bcrypt from 'bcrypt';

const pw = 'hihihi'

const generateSalt = async() => {
	return await bcrypt.getSalt(10);
}

const salt = generateSalt();

const hashPw = async(password) => {
	await bcrypt.hash(password, 10))
}

const userInput = 'hihihi'

hashPw(pw).then(console.log) 
hashPw(userInput).then(console.log)
//salt문자열이 달라지기 때문에 비밀번호가 같더라도 결과값이 달라진다. 

JWT 발행
양방향 암호화이기 때문에 복호화를 할 수 있는 secret key가 필요하다. key는 .env 파일 등에 저장을 해놓고 노출되지 않도록 사용해야 한다. jwt.verify시(인증 과정) 똑같은 secret key를 넣어야 한다.

//설치
npm install jsonwebtoken

실습

const makeToken = jwt.sign({ id:2 }, 'server_made_secret_key', { expiresIn: '1h' })

async function main() {
  console.log('token: ', token)
}

main()

참고 영상
https://opentutorials.org/course/3411/22097

profile
모르는것투성이
post-custom-banner

0개의 댓글