[nodeJS] bcrypt: hashed password와 plain password 를 어떻게 비교할까?

yoxxin·2022년 1월 4일
1

nodeJS

목록 보기
1/1
post-thumbnail

1. bcrypt

client의 아이디와 비밀번호를 DB에 저장 할 때,
보안을 위해 비밀번호는 암호화 해서 저장할 필요가 있다.
이때 사용하는 해시알고리즘 방법이 bcrypt이다.

설치방법

npm i bcrypt

2. bcrypt는 어떻게 서로 다른 hashed를 plain password와 잘 매치시킬까?

bcrypt를 사용해보면서
평문은 같은 값이지만 겉보기엔 전부 서로 다른 해시값들을
bcrypt.compare 를 이용해서 비교해보면 전부 true가 반환되니 신기했다.

import bcrypt from "bcrypt";

const saltRounds = 12;
const password = "1234";

// 암호화
const hashed = bcrypt.hashSync(password, saltRounds);
console.log(hashed);

console.log(bcrypt.compareSync(password, hashed)); // true

// password:1234, saltRounds:12로, 이전에 만든 hashed들
const h1 = "$2b$12$dbnukD8xfEU37zGzPFjGgOGkw5d0EMmlhAZm8bBRmJhdbElbNpHse";
const h2 = "$2b$12$Rw4pmHBD.ood7Fp4PVZWhOmf7YFOq66DeRVhBFeOER0eVhK53xRb.";
const h3 = "$2b$12$mCxMAQOKknkraedEXrSVBeTpstFNQGWSi5TLYxRAMx6TbNgIkyRge";
const h4 = "$2b$12$JTZUbIY//X7ltyQktEpb4.2GrG4YJE/c.pQ.QMDhv3eGCB.c71.m2";

console.log(bcrypt.compareSync(password, h1)); // true
console.log(bcrypt.compareSync(password, h2)); // true
console.log(bcrypt.compareSync(password, h3)); // true
console.log(bcrypt.compareSync(password, h4)); // true

"해시 할때마다 해시된 값이 다른데 어떻게 비밀번호를 비교할 수 있을까?"

3. 매치방법

bcrypt로 만든 해시값을 가져왔다.

$2b$12$dbnukD8xfEU37zGzPFjGgOGkw5d0EMmlhAZm8bBRmJhdbElbNpHse

각 문자들은 의미가 있는데,
$2b: bcrypt 알고리즘
$12: 2^12번 salt쳐서 hashing 반복
$dbnukD8xfEU37zGzPFjGgO: salt값
Gkw5d0EMmlhAZm8bBRmJhdbElbNpHse: plain password를 위 방법으로 hash한 결과값

즉, 해당 해시값이 어떤 salt를 사용했고, 몇번 반복했는지 포함되어 있으므로,
compare함수는 이 salt와 반복횟수를 이용해 plain password를 bcrypt 알고리즘으로 hash한 값
DB에 저장된 해시값과 같은지 비교하는 것이다.

+
긴 salt가 추가되고,
hash하는 횟수(cost)도 많아지면 (Key Stretching)
brute-force 공격을 이용한 레인보우 테이블을 만들기가 아주 힘들다고 한다.

0개의 댓글