Bcrypt 는 패스워드를 안전하게 보관할 수 있도록 패스워드를 해싱하는 알고리즘을 의미한다.
사용자가 가입을 할 때 입력한 아이디와 패스워드를 그대로 데이터베이스에 저장하면, 제 3자가 서버에 있는 데이터베이스 정보를 읽었을 때 사용자의 아이디 / 패스워드를 확인할 수 있고, 이를 악용할 수 있다.
bcrypt 구성
bcrypt 는 알고리즘에 대한 정보 / 암호화 복잡도(비용) / 암호화를 복잡하게 만드는 Salt / 암호화 된 정보로 구성되어있다.
굳이 Salt 를 이용하는 이유 ?
bcrypt 는 암호화를 하는데만 이용이 가능하다 . 패스워드를 암호화된 해시 데이터로 만드는건 가능하지만, 해시 데이터를 다시 패스워드로 변환하는 것은 불가능하다. 그렇다면, Salt가 없이도 안전할까 ?.. 그렇지 않다.🤔
해커들은 일반적으로 많이 사용하는 비밀번호들의 테이블을 가지고 있으며, 그것들을 해싱한 데이터들을 이미 다 가지고 있기때문에 해시 데이터를 비교하여 패스워드를 찾아내는 것이 가능하다.
Salt 를 사용하게 되면, 해커가 비교를 위해 가지고 있어야하는 테이블의 개수가 기하급수적으로 늘어나게 된다. 해킹을 막을 수 있는 완전한 방법은 없으나, 해킹을 쉽게 할 수 없도록 조치하는 방법이라 볼 수 있다.
정리하면, bcrypt 는 암호를 해싱할 수 있는 알고리즘이고, 단방향이다. (패스워드를 해싱만 가능하고, 해싱된 결과를 다시 패스워드로 변환할 수 없음) 암호화 할 때 그냥 암호화하는 것이 아닌, 랜덤한 문자열을 이용하여 암호화를 조금 더 복잡하게 만들 수 있다.
Nodejs – bcrypt 테스트
const bcrypt = require("bcrypt"); const password = "abcd1234"; const hashed = bcrypt.hashSync(password, 10); // 동기 해시 함수 (salt 길이 10) console.log(`password : ${password}, hashed : ${hashed}`); //password : abcd1234, hashed : $2b$10$GEzFYlCSoHNGyoi8LdKapubA8RP0Nz2nEowor5wPXH0Nz0leMw91O const result = bcrypt.compareSync("abcd1234", hashed); // 동기 비교 함수 console.log(result); // true
그럼 Salt가 무조건 길수록 좋을까 ?
Salt 길이가 길어질수록 (복잡도가 증가할수록) 해시를 하는데 걸리는 시간이 기하급수적으로 늘어난다. 즉, Salt 가 너무 긴 것도 좋은 것은 아니다. (사용자가 가입을 할때마다 서버의 cpu 가 암호화를 위한 계산을 진행하기 때문)
보통 Salt 길이는 서버의 사양이나 서비스에 따라 다르지만, 8~12 정도가 적당하다.
https://auth0.com/blog/hashing-in-action-understanding-bcrypt/