비밀번호 안전하게 저장하기

YiJaeE·2022년 7월 24일
0

많은 서비스들이 사용자의 정보를 서버에 저장합니다. 가장 대표적인 사용자의 정보라면 아이디와 비밀번호를 들 수 있습니다. 오늘은 사용자의 비밀번호를 어떻게 암호화해서 서버에 전달하는지에 대해서 작성하려고 합니다. 비밀번호를 암호화할 때 사용한 패키지는 bcrypt입니다.

암호화 방식

보통 비밀번호를 저장할 때는 해시 함수를 통해 암호화된 비밀번호를 만들어 전송하게 됩니다. 예를 들어 어떤 사용자가 비밀번호를 abcd로 변경했다면 이 텍스트를 그대로 전송할 경우 보안의 위험이 크기 때문에 권장되지 않습니다. 때문에 사용자가 입력한 텍스트를 암호화해, 이 암호화된 메세지로는 원본 텍스트를 구할 수 없도록 하고 있습니다.

대부분의 웹사이트에서는 암호화를 하기 위한 해시 알고리즘으로 SHA-256을 사용합니다. 256비트로 구성되어있고 64자리의 문자열을 반환해주는 방식입니다. 이 방식을 사용하면 암호화된 문자열만으로는 원본 텍스트를 유추할 수 없는 단방향 암호화 방식입니다. 서버는 이렇게 생성된 암호화된 메세지 즉 다이제스트끼리의 비교를 통해 같은 다이제스트라면 로그인을 승인하는 형태로 서비스를 이용할 수 있도록 합니다.

그러나 단방향 해시 함수가 갖는 문제점도 있습니다. 동일한 텍스트가 언제나 동일한 값을 반환한다면 웹사이트를 공격하려는 사람이 최대한 많은 다이제스트를 확보한 뒤 원본 텍스트를 찾아내는 것이 가능하기 때문입니다. 이러한 문제점을 보완하기 위해 '솔팅'이라는 임의의 문자열을 추가하는 방법을 사용하게 됩니다.

solt

솔트는 단방향 해시 함수에서 다이제스트를 생성할 때 추가하는 바이트 단위 임의의 문자열입니다. 이 방법을 사용하면 웹사이트를 공격하려는 사람이 원본 텍스트의 다이제스트를 알게 되더라도 솔팅된 다이제스트로 비밀번호가 일치하는지 여부를 확인하기 어렵습니다. 사용자별로 다른 솔트를 사용하게 된다면 더더욱 일치 여부를 확인하기 어렵게 됩니다.

bcrypt

bcrypt는 비밀번호 저장을 목적으로 설계된 해시 매커니즘 중 하나입니다. 위에서 설명한 솔팅 방식을 사용하기 때문에 보안에 유리한 방식이라고 볼 수 있습니다. 이 패키지를 사용하면 생성한 솔트와 함께 비밀번호를 해시해 서버에 전송하는 것을 쉽게 만들어줍니다.

위 화면은 네이버의 비밀번호 변경 화면입니다. 많은 웹사이트들이 네이버처럼 현재 비밀번호와 새 비밀번호를 입력하도록 권장하고 있습니다. bcrypt를 사용해 기존 비밀번호와의 비교, 그리고 새 해시 비밀번호를 생성하는 과정을 다음과 같이 작성할 수 있습니다. 저는 디비에서 솔트를 받아오고, 새로운 해시 비밀번호를 전송하는 형태로 구현했습니다.

const info = req.body;
const hashedOldPassword = bcrypt.hashSync(oldPass, info.salt);
if (hashedOldPassword === info.hasHashedPassword) {
  const newSalt = bcrypt.genSaltSync(10);
  const hashedNewPassword = bcrypt.hashSync(info.newPass, newSalt);
  
  // 여기까지의 작업이 끝나면 새로운 솔트와 새로운 해시 비밀번호를 서버로 전송하면 됩니다.
}

마무리

패키지를 사용하면 별로 어렵지 않게 비밀번호 암호화를 구현할 수 있습니다. 처음 비밀번호 암호화를 구현할 때 해시한 비밀번호를 보내야 한다는 이야기를 듣고 당황했던 기억이 나네요ㅎㅎ 사실 구현 자체는 어렵지 않은데 왜 이런 방식으로 해야하는지 이해하는데 더 많은 시간이 걸렸던 것 같습니다. 기록을 남기기 위해 즐겨찾기 했던 블로그들을 찾아서 읽으면서 좀 더 이해할 수 있게 된 것 같습니다.


안전한 패스워드 저장
[Node.js] 패스워드 안전하게 저장하기, node의 bcrypt

profile
개발을 개발개발 🐾

0개의 댓글