What is bcrypt hash?
Hash function
bcrypt hash는 Hash function의 일종이다.
Hash function은 암호화를 할 때 주로 사용하는 함수인데, 암호화하고자 하는 대상을 인자로 복잡한 함수를 돌리고, 함수에서 나온 결과물을 사용하는 방법이다.
예컨데 다음과 같다.
우리의 소원은 통일이라니,,,몇 년 전 자료인지 궁금하다.
Hash function의 특징으로는 단방향적이며, 위의 예시처럼 한 글자만 달라지더라도 함수를 돌린 값이 완전히 달라진다는 것이 있다. 물론 같은 input을 집어넣으면 항상 일정한 값을 도출한다.
그러나 이러한 Hash function도 완벽한 암호화 시스템은 아니다. 그럴만 한 것이 암호화를 할 때 사용한 Hash function이 무엇인지 알고 있다면 미리 여러 값을 같은 함수를 통해 돌려보고 그 결과를 저장해둔 다음 해당 리스트에서 사용자의 암호(해시 값)을 찾아보기만 하면 되기 때문이다. 이를 Rainbow Table이라고 한다.
따라서 엔지니어들은 이 문제를 해결하기 위해 Salt라는 방법을 고안했다.
Salt
소금을 뜻하는 그 salt가 맞다. 우리가 음식을 할 때 소금을 뿌리듯, Hash function에 값을 집어넣기 전에 salt를 추가하는 것이다. 문자열 앞뒤로 salt를 추가하고 함수를 돌리면 salt 또한 무작위 생성된 값이기 때문에 더더욱 역추적하는 것이 어려워진다.
Code
app.post('/signIn', function(req, res){
let sql = 'INSERT INTO user SET ?'
bcrypt.genSalt(saltRounds, function (error, salt) {
if (error) throw error;
bcrypt.hash(req.body.password, salt, function (error, hashedPassword) {
if (error) throw error;
let user = {
id : req.body.id,
password : hashedPassword,
salt : salt,
}
connection.query(sql, user, function(error, result){
if(error) throw error;
console.log('sign in 성공')
})
})
})
res.end()
})
위 코드가 sign in할 때 BE에서 DB에 입력받은 id 값과 salt를 추가해 함수를 돌린 password 그리고 login할 때 password를 확인하기 위한 용도의 salt를 넣어주는 코드이다.
app.post('/login', function(req, res){
const {id, password} = req.body
connection.query(`SELECT * FROM user WHERE id="${id}"`, function(error, result){
if (error) throw error
if (result.length) {
if (error) throw error;
bcrypt.hash(password, result[0].salt, function (error, hashedPassword) {
if (error) throw error;
if (result[0].password === hashedPassword){
console.log('login 성공');
msg = result[0].id
}
else{
console.log('login 실패');
}
})
}
else{
console.log('login 실패');
}
})
res.end()
})
위 코드는 입력받은 id가 같은 지 비교하고, 입력받은 password를 salt값을 DB에서 가져와 똑같은 조건에서 bcrypt를 돌려 맞는 password인 지 확인하는 코드이다.
후기
사실 DB에 salt 값을 넣어도 되는 지는 확신이 안 선다. 넣으면 안될 거 같다. 왜냐하면 해킹을 통해 해당 DB에 접근하기만 하면 해시 값 있고, salt 있어서 원래 password를 유추하기가 쉬울 것 같기 때문이다. 그런데 또 어차피 saltRounds 값과 무슨 Hash function을 사용했는 지 모르기 때문에 괜찮지 않을까 싶기도 하다. 이건 위에 내용을 쓰다가 떠오른 생각이다. 또한 query를 이용해 데이터베이스와 연동시키는 첫 시도였는데 매우 재미있었다. 상투적인 표현이긴 하지만 정말 재밌었다.
NO SBL KEEP GOING