이제 당당한 로그인 API 설계자(?)가 되었다는 뽕에 차기에는
아직도 내가 갈 길은 멀다!
미약한 내 실력으로 만약 배포 단계까지 가게 되었는데,
데이터베이스가 탈탈 털린다면?😱
이에 대한 보안 대책 1단계를 세워보려고 한다!
바로 비밀번호 암호화!
새삼 개발 겉핥러라는 걸 매번 깨닫는데
오늘 내가 겉핥았던 것은 바로 비밀번호는 그냥 저장되었을 것이라는 것!
사실은 그게 아니었습니다
Bcrypt는 단방향 해시 함수 중 하나로
주로 사용자 비밀번호를 안전하게 저장하기 위해 사용된다
해시함수란 어떤 입력값을 특정 길이의 문자열로 변환해주는 암호함수라고 생각하면 된다
간단하게 예를 들어보자면
const ranNum = Math.floor(Math.random()*10000)
console.log(ranNum)
// 9697
const func = (num) => {
return num % 10
}
func(ranNum)
// 3
이처럼 특정 숫자를 10으로 나눈 나머지를 구하는 함수도 해시함수이다
어떤 숫자를 넣든 한자리 숫자로 변환을 할 수 있기 때문!
근데 그게 단방향이다?
한번 가면 돌아오지 못한다고 생각하면 된다..
즉, 암호화는 되는데 복호화(역함호화)가 안되는 것
(더 간단하게, 한번 암호화 해버리면 원본을 알 수가 없다..)
하지만 이 부분을 조금 더 정교하게 만들면
원본을 알 수는 없지만, 결과값을 알고 해시함수의 구조(10으로 나눈 나머지)를 알면
원본과 암호화된 함수가 같은 값을 가지는 지는 알 수 있다!
(이게 바로 뽀.인.트.)
그래도 이해가 안된다면 해시함수를 체험할 수 있는 곳이 있다!
이 곳 에서 아무 글자나 입력해보시라
한글자를 넣거나, 긴 문장을 넣어도 출력물은
고양이가 키보드 위에서 같은 시간 동안 춤을 춘것 같은
일정 길이의 문자열이 계속해서 나올 것이다
이제 좀 감이 잡히지?
이어서 조금 더 알아보자
일단 터미널 창을 열고 설치를 한다
npm install bcrypt
그리고 코드 적용은 아래와 같이
## javascript
const bcrypt = require('bcrypt');
// 솔팅 설정 주로 10 ~ 13이 권장된다
// 그 이하는 복잡도가 떨어져 보안이 취약해지고, 그 이상은 암호화가 시간이 길어지기때문
const saltRounds = 10;
// 암호화되기 전인 유저가 입력한 패스워드 원본
const plaintextPassword = 'mySecurePassword';
// 암호화
bcrypt.hash(plaintextPassword, saltRounds);
// 이후 이 암호화된 비밀번호를 데이터베이스에 저장
...
// 데이터베이스에서 받아온 암호화된 비밀번호
const hashedPasswordFromDB = '...';
// 이후 로그인한 유저의 비밀번호를 받아 두 데이터가 일치하는지 확인
bcrypt.compare(plaintextPassword, hashedPasswordFromDB);
이렇게 우리는 사용자가 입력하는 비밀번호를 알 필요도 없거니와
알 수도 없는 비밀번호 중개사(?)로 한 발짝 물러설 수 있게되었다!
(물론 중간에 빼서 볼 수는 있지만..)
이런식으로 비밀번호를 처리하다 보니
잃어버린 비밀번호를 찾아주는 것이 아닌 재발급을 해주는 방식으로
은근슬쩍 바뀐게 아닌가 생각이 든다(인지는 못했지만 언제부터인가 그렇게 바뀌어있다)
그리고 이전에 쓰던 비밀번호를 알려주는게 많이 위험하기도 하고..
(항상 보안정책에 맞춰 대/소문자, 숫자, 특수문자를 쓰지만 우리는 대부분의 사이트에서 같은 비밀번호를 사용하는걸 알고 있지 않은가..?)
Bcrypt는 안전한 비밀번호 저장을 위한 강력하고 신뢰성 있는 해시 함수로
비밀번호 보안에 중요한 역할을 한다
하지만 그럼에도 불구하고 변수는 항상 있게 마련
장인은 도구 탓을 하지 않기에 우리는 이 도구를 항상 올바르게 사용해야 한다.
항상 취약점은 발견되기 마련이므로 라이브러리 업데이트는 꼭 주기적으로 확인해주는 것이 좋다!
++
발돋움 중인 예비 개발자 입니다.
태클 및 의견 공유 언제나 환영 :D