-
[security] hashing password with bcryptBack-end 2021. 12. 10. 01:23
비밀번호의 보안?
백 엔드에서 유저의 비밀번호를 데이터베이스에 그대로 저장하는 경우가 있을까요? 🐱 그 것은 정말 엉망진창의 보안일 것입니다. 누군가가 데이터베이스에 접근 하더라도 유저의 비밀번호는 확인할 수 없어야하지만, 우리는 비밀번호를 Compare하여 로그인을 진행하여야 하기 때문에 비밀번호의 데이터베이스 저장은 필수불가결합니다. 그렇다면 어떻게 우리는 비밀번호를 숨길 수 있을까요?
"그 것은 비밀번호를 Hashing 하는 것 입니다."
우선 비밀번호 해쉬화 알고리즘은 예전부터 발달되어 오던 기술입니다. 해싱에 관한 많은 알고리즘이 있지요. 그 중 우리는 Blowfish를 이용한 Bcrypt를 이용하여 비밀번호를 해싱할 것입니다. 많은 다양한 기술이 있습니다만 ex) SHA SHA를 사용하는 암호화는 빠른 연산의 GPU 공격에 취약하기 때문에 (SHA 암호화는 GPU 연산에 유리한 32비트 논리 및 산술 연산에만 사용됩니다.
따라서 우리는 공격자의 속도를 늦춰야할 필요가 있기 때문에 bycrypt를 기용하기로 합니다.
한번 해싱된 비밀번호는 절대 복호화가 불가능하며, 이 것은 단방향 함수이기 때문에 원래의 비밀번호를 해싱된 비밀번호와 비교하는 것 밖에 하지 못할 것입니다.
bycrypt algorihm 감사하게도 우리는 이미 구현된 패키지에 의해 bcrypt를 간단하게 구현할 수 있습니다.
npm install bcrypt
데이터베이스에 넣기 전 우리는 유저에게 비밀번호를 input으로 받아올 것 입니다. 데이터베이스에 INSERT하기 전 우리는 bcrypt의 hash메소드를 통해 비밀번호를 해싱합니다.
async hashPassword(): Promise<void> { try { this.password = await bcrypt.hash(this.password, 10); } catch (error) { console.log(error); throw new InternalServerErrorException(); } }
bcrypt의 default around (즉, 비밀번호를 얼마나 강하게 솔팅할 것인지를 정한다고 생각하면 편합니다.) 는 10입니다. 다음과 같이 비밀번호를 해싱하면 우리는 유저가 제공한 비밀번호를 Hashing할 수 있습니다.
이렇게 Hashing된 비밀번호와 다시 유저의 로그인 요청 시 받아온 비밀번호를 비교하기 위해 다음과 같은 함수를 작성할 수 있습니다.
async checkPassword(notSaltPassword: string): Promise<boolean> { try { const compareOk = await bcrypt.compare(notSaltPassword, this.password); return compareOk; } catch (error) { console.log(error); throw new InternalServerErrorException(); } }
마찬가지로, bcrypt의 compare메소드를 통하여 유저의 로그인 요청 시 받아온 비밀번호와 데이터베이스의 salting된 비밀번호를 비교하여 우리는 true or false를 return 할 수 있을 것이고 비밀번호를 비교할 수 있을 것입니다.
이렇게 굉장히 중요한 비밀번호 암호화 기법 중 하나인 bcrypt에 대해 알아보았습니다. 도움이 되셨다면 좋을 것 같습니다🧤
'Back-end' 카테고리의 다른 글
[AWS S3, Nest.js] Nest.js에서 file S3에 저장하기 (0) 2022.01.24 [Nest.js, Guard, Save request] Guard를 활용한 엔드포인트 보호 (0) 2021.12.13 [Authentication, Nest.js, JWT] Nest.js에서 JWT 동적모듈,미들웨어 구현해보기 (0) 2021.12.12 [Nest.js] TypeORM 사용기 (0) 2021.12.09 [Nest.js, Graphql] 간단하게 Nest.js와 Graphql 기반의 프로젝트 구성하는 법 (0) 2021.12.08