GPT 요약
My-Books 프로젝트에서 로그인 절차를 설계하며, 평문 비밀번호 전송 문제를 해결하기 위해 고민했습니다.
기존에 Back Server에서 비밀번호를 암호화하던 방식을 Front Server에서 해싱 후 전달하는 방식으로 변경해 보안성을 강화했습니다.
로그인 요청은 호출 빈도가 낮아 추가적인 서버 호출 비용보다 보안성을 우선시하는 선택이 이루어졌습니다.
My-Books 프로젝트에서의 경험을 다룬 글입니다.
My-Books 프로젝트에서 제가 맡은 역할은 인증/인가 프로세스를 설계하고 구현하는 것이었습니다.
특히 로그인 절차(인증)를 구현하면서 가장 큰 고민은 평문과 비문의 사용과 이를 어떻게 안전하게 처리할 것인가에 대한 것이었습니다.
이번 글에서는 이러한 고민의 과정과 최종적으로 내린 선택에 대해 공유하려 합니다.
BCrypt를 어디에 사용할 것인가?
로그인 설계에서 가장 중요한 고민 중 하나는 BCrypt를 어디에서 사용할 것인가 하는 점이었습니다.
초기 설계
초기에는 프론트에서 평문 비밀번호를 받아 이를 백으로 넘긴 후 BCrypt로 암호화하고, 데이터베이스와 비교해 검증하는 방식으로 설계했습니다.
이는 일반적으로 많이 사용하는 방법으로, 간단하고 직관적이라는 장점이 있었습니다.
최종 설계
하지만 최종적으로는 프론트에서 사용자가 입력한 이메일을 백으로 전달해 검증하고 DB에 저장돼있는 비문과 입력한 비밀번호를 BCrypt를 통해 검증한 뒤 로그인 절차를 완료하는 방법을 선택했습니다.
이로 인해 로그인 절차는 다소 복잡해졌고, 백서버 호출도 기존 1번에서 2번으로 증가하게 되었습니다.
왜 변경했을까?
이건 정말 단순한 이유인데요, 저는 평문 비밀번호가 통신 과정에서 평문으로 전송되는 것 자체가 너무 찝찝했습니다.
물론 HTTPS를 사용하면 암호화된 통신을 보장할 수 있지만 비밀번호 같은 민감한 데이터는 단 한 번이라도 평문으로 노출될 가능성을 없애는 게 중요하다고 생각했습니다.
또한 로그인 요청은 사용자가 자주 호출하지 않는 기능입니다.
대부분 사용자가 서비스를 시작하거나, 토큰이 만료된 후 로그인을 수행하기 때문에 호출 빈도가 비교적 낮습니다.
따라서 로그인 절차에서 발생하는 추가적인 서버 호출 비용은 최소화된 부담이라고 판단했습니다.
비용 최적화를 추구할 수도 있었지만, 보안성을 강화하는 선택이 사용자의 민감한 정보를 다루는 인증 시스템의목표와 일치한다고 결론 내렸습니다
BCrypt 값 검증 방식
또한 다음과 같은 질문도 받게 되었는데요
Q: 프론트,백 둘 다 BCrypt를 사용하고 프론트에서 암호화 한 후 전송한다음에 백에서 확인하면 한번으로 처리가능한거 아니에요?
A: BCrypt를 이용해 값의 일치를 확인하려면 평문하나와 비문 하나가 필요해서 안될것 같아요
이 것을 이해하려면 BCrypt의 동작 구조를 알아야 하는데요 BCrypt는 단방향 해쉬 알고리즘으로 한번 암호화하면 본문을 알 수 없게됩니다.
그런데... 원문을 알 수 없는데 어떻게 입력한 비밀번호와 DB의 암호화된 비밀번호가 같다는 것을 알 수 있을까요??
정답은 간단하게도 다시 암호화를 시킨후 비교합니다.
Bcrypt는 내부적으로 Salt(임의의 값)를 생성하여 평문 비밀번호와 함께 해싱 알고리즘을 적용합니다.
생성된 Salt는 해싱 결과(비문)에 포함되며, 검증 시 동일한 Salt를 추출해 평문 비밀번호와 함께 다시 해싱합니다.
이렇게 생성된 비문이 기존 비문과 같다면, 암호화되기 전의 평문이 동일했음을 확인할 수 있습니다.
따라서.. 들어온 평문과 암호화된 비문이 같음을 알기 위해서는 무조건 평문 하나와 비문 하나가 필요하기 때문에
백서버에서 비문 비밀번호를 응답으로 받은 후 프론트에서 들어온 평문을 이용해 검증하는 방식을 사용해야 합니다.
My-Books 로그인 절차
최종적으로 설계된 My-Books 로그인 절차는 다음과 같은 흐름으로 진행됩니다.
- 이메일과 비밀번호 입력
- 사용자가 이메일과 비밀번호를 입력하여 로그인을 시도합니다. 이 정보는 Front Server를 통해 Gateway Server로 전달
- 이메일 인증 요청
- Gateway Server는 Back Server로 이메일 인증 요청을 전송
- 이메일 인증 실패 시: 로그인 절차가 중단되고, 인증 실패 응답이 반환
- 이메일 인증 성공 시: Back Server는 암호화된 비밀번호(BCrypt로 해싱된 값)를 Gateway Server를 통해 Front Server로 응답
- 비밀번호 검증
- 사용자가 입력한 평문 비밀번호와 Back Server에서 전달받은 암호화된 비밀번호를 비교하여 검증
- 비밀번호 검증 실패 시: 인증 실패 응답이 반환
- 비밀번호 검증 성공 시: 로그인 절차 진행 , 마지막 로그인 시간 갱신 및 포인트 적립 요청
- 토큰 발급
- 토큰 발급 후 로그인처리 완료
시퀀스 다이어그램을 통해서 보면 다음과 같습니다.(Resource Server는 Back Server와 동일)
추가적으로 같이 보시면 좋은 발표 영상입니다.
'프로젝트 > My-Books' 카테고리의 다른 글
Gateway로 인가 로직, 어떻게 최적화했을까? (0) | 2024.12.22 |
---|---|
JWT 만료기간, 보안과 사용자 경험의 Trade-Off (3) | 2024.12.21 |
JWT 안전성 개선기 (0) | 2024.12.20 |
Spring Security 없이 효율적인 인가 구현하기 (1) | 2024.12.20 |
JWT는 왜 사용할까? (1) | 2024.12.20 |