crypto
누군가의 공격으로 데이터베이스가 유출될 경우 사용자가 큰 피해를 입을 수 있기 때문에 비밀번호는 암호화해서 저장해야 한다. node.js에는 암호화를 할 수 있는 내장 모듈인 'crypto'가 있다.
const crypto = require('crypto');
const password = "1111";
const salt = crypto.randomBytes(64).toString('base64');
const hashPassword = crypto.pbkdf2Sync(password, salt, 10000, 64, 'sha512').toString('base64');
console.log(hashPassword);
pbkdf2Sync(원문, 솔트, 해시 함수반복 횟수, 출력 바이트 수, 해시 알고리즘) 메서드로 원문을 암호화할 수 있다.
- 원문 비밀번호에 솔트를 더한다.
- 1에 대해 해시 함수를 N번 반복한다.
- 2의 결과로 나온 암호화된 비밀번호와 솔트를 데이터베이스에 저장한다.
솔트도 데이터베이스에 저장하는 이유는 pbkdf2Sync 메서드가 암호화만 할 수 있고, 복호화는 할 수 없는 단방향 암호화이기 때문이다. 솔트도 저장해 놔야 사용자를 로그인시켜줄 수 있다.
해시 함수를 여러 번 사용하는 이유
사용한 해시 함수의 종류와 해시 함수에 몇 번을 돌릴지는 개발자만 알고 있다. 그래서 해커는 사용된 해시 함수의 종류와 해시 함수를 몇 번 돌려야 하는지도 알아내야 하며, 해커가 함수를 돌리는 횟수를 알아냈다고 해도 큰 횟수를 지정해 놓았다면 한 번 암호화하는 데에 시간이 많이 소모된다.
사용자는 비밀번호를 확인하는데 0.5초 정도 걸려도 별 문제가 없지만 해커의 경우는 다르다.
웬만한 게임은 쾌적하게 돌릴수 있는 그래픽카드를 사용하면 대략 1초에 6억 번의 해시 알고리즘을 수행할 수 있다고 한다. 하지만 해시 함수 반복 횟수를 크게 설정하면 0.5초에 1번의 결과를 얻을 수 있게 되므로 해커 입장에서는 치명적이다.
결과적으로 무차별적으로 값을 대입해 보는 공격(브루트 포스)을 막을 수 있다.
salt를 사용하는 이유
사용자 A와 B가 모두 "1234"라는 비밀번호를 사용하고, "1234"를 해시 함수에 여러 번 돌려서 DB에 저장했다고 가정해 보자.
이 상황에서 해커가 DB에 접근해서 사용자 A의 비밀번호 평문이 무엇인지 알아내는데에 성공했다. 그러면 해커는 사용자 B의 평문 비밀번호가 무엇인지도 알 수 있게 될 것이다.
위 그림과 같이 해커가 평문-암호화 비밀번호 테이블을 만들어놓고 데이터베이스에 있는 사용자들의 비밀번호를 알아내는 게 가능해진다는 뜻이다.
그래서 같은 비밀번호를 암호화해도 같은 암호문이 되지 않도록 원본 비밀번호에 랜덤한 문자열을 덧붙여 암호화한다. 여기서 덧붙여지는 문자열을 salt라고 한다.
'데브코스' 카테고리의 다른 글
[8주차 - DAY1] 도서 API 구현(3) (0) | 2024.04.15 |
---|---|
[7주차 - DAY5] 도서 API 구현(2) (0) | 2024.04.12 |
[7주차 - DAY4] 도서 API 구현 (0) | 2024.04.11 |
[7주차 - DAY3] 사용자 API 구현 & 비밀번호 암호화 (0) | 2024.04.10 |
[7주차 - DAY2] 도서 정보 API 설계 및 구현 (0) | 2024.04.09 |