wikipedia에서 bcrypt는 다음과 같이 정의되어있다.
블로피시 암호에 기반을 둔 암호화 해시 함수로써 암호를 hash하는데 도움을 주는 node.js의 라이브러리이다. rainbow table 공격 방지를 위해 salt를 통합한 bcrypt는 적응형 함수의 하나다.
암호화 해시 함수란 해시 값으로부터 원래의 입력값과의 관계를 찾기 어려운 성질을 가지는 경우를 의미한다. 만약 입력값과의 관계가 유추된다면 보안이 취약해진다.
rainbow table은 해시 함수를 사용하여 변환 가능한 모든 해시 값을 저장시켜 놓은 표이다. 보통 해시 함수를 이용하여 저장된 비밀번호로부터 원래의 비밀번호를 추출해 내는데 사용된다.
Bcrypt는 salt를 통합하여 해당 공격을 방지했다고 하는데, 솔트(salt)는 데이터, 비밀번호, 통과암호를 해시 처리하는 단방향 함수의 추가 입력으로 사용되는 랜덤 데이터로써 해시 함수를 사용해 변환된 데이터만으로는 유추할 수 없도록 한다.
즉, Bcrypt는 해시값으로 부터 원래의 입력값을 유추하기 어려운 암호화 해시 함수로, 랜덤한 데이터(salt)를 부여해 더욱 보안을 높인 node.js의 라이브러리이다.
client에서 보내준 비밀번호 등을 암호화하지 않고 그대로 Server에 저장하게 되면 보안상 너무 취약하기 때문에 보낸 후 암호화해서 DB에 저장해 관리해야한다. 그러기 위해서는 Bcrypt를 이용해서 비밀번호를 암호화하는 과정이 필요하다.
npm install bcrypt --save
위의 명령어를 통해 bcrypt를 설치해준다.
2-1. User.js 수정
const bcrypt = require("bcrypt");
userSchema.pre("save", function (next) {});
bcrypt를 import해주고, 유저 모델에 유저가 저장되기 전에 무언가의 전처리를 해준 뒤 후작업을 할 수 있도록 한다. next callback 함수는 전처리를 해준 뒤 멈추어있지 않고, 후작업을 위해 처리한 것을 넘겨주는 역할을 한다.
const saltRounds = 10;
bcrypt.genSalt(saltRounds, function (err, salt) {
bcrypt.hash(myPlaintextPassword, salt, function (err, hash) {
});
});
bcrypt는 salt를 생성하고 생성된 salt로 비밀번호를 암호화한다. salt를 이용한 암호화 과정은 salt를 먼저 생성 한 후에 saltRound로 salt가 몇 자인지 나타낸다. 만약 saltRound를 10자리라고 선언했다면 10자리인 salt를 이용해서 비밀번호를 암호화한다.
const saltRounds = 10;
userSchema.pre("save", function (next) {
let user = this;
if (user.isModified("password")) {
//비밀번호를 암호화 시킨다.
bcrypt.genSalt(saltRounds, function (err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
} else {
next();
}
});
위의 기본 세팅을 토대로 세팅한 뒤 genSalt를 이용해서 salt를 만들고 salt가 잘 만들어졌다면 hash값(암호화 된 비밀번호)과 plainPassword(user.password)의 값을 교체한다.
여기서 조건문을 이용해 처리해주는 이유는 비밀번호가 아닌 다른 userSchema에 있는 정보를 변경해서 새로 저장할 때 마다 다시 비밀번호를 암호화하는 과정은 바람직 하지 않기 때문에 비밀번호가 수정될 때만 암호화 하도록 isModified를 이용해서 조건문을 부여하고, 만약 비밀번호가 수정된 것이 아니라면 바로 next() callback funtion을 호출해서 다음으로 넘겨준다.
MongoDB에서 기존의 회원가입 된 것과 암호화를 구현하고 난 뒤 회원가입한 것의 비밀번호를 살펴보면 요렇게 암호화되어 잘 넘어가는 것을 볼 수 있다.👍
갑자기 난이도가 훅 올라가서 너무 어렵다.🥲
따라하며 배우는 노드, 리액트 시리즈 - 기본 강의 를 공부하며 작성한 글입니다.