사용자의 비밀번호를 데이터베이스에 저장할 때 비밀번호를 그대로 저장하게 되면 매우 위험하다. 만약 데이터베이스가 털리게 되면 사용자들의 비밀번호가 그대로 노출되기 때문이다. 따라서 사용자들의 비밀번호는 일종의 해싱 알고리즘을 통해 암호화 된 방식으로 데이터베이스에 저장한다.
사용자의 비밀번호가 test1234라고 하면 이를 해싱 알고리즘에 대입하여 위와 같이 겉으로 보기엔 랜덤한(?) 긴 스트링으로 암호화하여 저장한다. 그렇지만 저 형태로만은 100% 안전하지 않다. 왜냐하면 해커들의 리버스 엔지니어링을 통해 해싱되기 전 암호를 유추할 수 있는 가능성이 있기 때문이다. 따라서 해싱의 재료로 솔트라는 것을 이용한다.
이런식으로 원래의 비밀번호 앞에 여분으로 붙이는 임의의 텍스트를 솔트라고 한다. 솔트를 통해 해커들이 쉽게 원래의 비밀번호를 유추할 수 없게 하는 것이다. 보통 이 솔트 값은 유저 정보를 담은 데이터베이스에 함께 저장된다고 한다.
Node.js에서는 bcrypt 패키지를 사용하여 비밀번호를 쉽게 해싱할 수 있다.
먼저 bcrypt 패키지를 설치해보자. 터미널에서 npm을 사용하여 설치한다.
npm install bcrypt
필자는 데이터베이스로 MongoDB를 사용했다. 다음과 같이 간단한 유저 스키마에 bcrypt를 사용해보겠다.
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const userSchema = new mongoose.Schema({
email: {
type: String,
required: [true, "Please enter an email"],
unique: true,
lowercase: true,
},
password: {
type: String,
required: [true, "Please enter an password"],
minlength: [6, "Minimum password length is 6 characters"],
},
});
클라이언트로부터 유저 이메일과 비밀번호를 받고 데이터베이스에 저장하기 '전'에 비밀번호를 해싱 해야한다. 따라서 mongoose의 pre메소드를 사용한다.
userSchema.pre("save", async function (next) {
const salt = await bcrypt.genSalt(); // salt 생성
this.password = await bcrypt.hash(this.password, salt); // 비밀번호 해싱
next();
});
다음과 같이 bcrypt 패키지를 사용하여 솔트 생성과 비밀번호 해싱을 매우 간단하게 할 수 있다.
이 후 데이터베이스를 보면
다음과 같이 해싱된 형태로 비밀번호가 저장된다.
해싱 알고리즘은 파보면 매우매우 복잡하지만 bcrypt를 사용하면 매우 편하게 비밀번호를 해싱할 수 있다. 보안을 위해 꼭꼭 사용하자!