목차
요구사항
Lv.3에서 추가한 비밀번호 필드에 들어가는 비밀번호를 암호화합니다.
- ✅ 암호화를 위한 PasswordEncoder를 직접 만들어 사용합니다.
요구 구현
build.gradle
더보기
dependencies {
implementation 'at.favre.lib:bcrypt:0.10.2'
}
- `at.favre.lib`라는 그룹에서 제공하는 `bcrypt` 라이브러리의 `버전 0.10.2`를 프로젝트에 추가합니다.
- Bcrypt 해시 함수를 Java에서 사용할 수 있게해주는 라이브러리입니다.
- 평문 비밀번호를 안전하게 해싱합니다. (암호화)
- 해시된 비밀번호와 사용자가 입력한 비밀번호를 비교하여 검증
PasswordEncoder
더보기
@Component
public class PasswordEncoder {
public String encode(String rawPassword) {
return BCrypt.withDefaults().hashToString(BCrypt.MIN_COST, rawPassword.toCharArray());
}
public boolean matches(String rawPassword, String encodedPassword) {
BCrypt.Result result = BCrypt.verifyer().verify(rawPassword.toCharArray(), encodedPassword);
return result.verified;
}
}
1. encode() 코드 설명
- `BCrypt.withDefaults()` : 기본 설정을 사용해 Bcrypt 인스턴스를 생성합니다
- `hashToString(...)` : 비밀번호를 해싱하여 문자열 형태의 해시값을 반환합니다.
- `BCrypt.MIN_COST` : `Cost Factor`가 들어가는 자리입니다.
- `rawPassword.toCharArray()` : 보안상 char 배열로 변환 (Java에서는 문자열은 불변이므로 보안상 취약할 수 있습니다.)
- 출력 결과
더보기

Cost Factor란?
`Cost Factor` : 해싱 알고리즘의 복잡도를 조절하는 숫자입니다.
`2^cost`만큼의 연산을 수행하므로, 값이 클수록 해싱 속도는 느려지고 보안이 강해집니다.
Cost Factor | 연산 횟수 | 보안 수준 | 속도 |
4 (`MIN_COST`) | 2⁴ = 16 회 | 매우 낮음 (테스트용) | 매우 빠름 |
10 (기본값) | 2¹⁰ = 1,024 회 | 보통 (실사용 가능) | 중간 |
12 | 4,096 회 | 안전함 | 느림 |
14+ | 16,384+ 회 | 매우 안전 | 느림 |

다음과 같이 상수로 값이 정의되어있습니다.
2. matches 코드 설명
- 입력
- `rawPassword` : 사용자가 로그인할 때 입력한 평문 비밀번호입니다.
- `encodePassword` : 저장된 해시 비밀번호 (데이터베이스에서 꺼낸 값)
- 동작
- `BCrypt.verifyer().verify(...) : 주어진 평문 비밀번호를 기존 해시값과 비교
- `result.verified` : 비밀번호가 일치하면 `true`, 아니면 `false`
- 출력 : 두 비밀번호가 일치하는지 여부 (`true`/ `false`)
LoginService
더보기
@Service
@RequiredArgsConstructor
public class LoginService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public void login(LoginRequestDto requestDto, HttpServletRequest request) {
// 유저 이메일 검증
User user = userRepository.findByEmailOrElseThrow(requestDto.getEmail());
// 비밀 번호 검증
boolean matches = passwordEncoder.matches(requestDto.getPassword(), user.getPassword());
// 비밀 번호 검증 후 예외 발생
if (!matches) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "This password is incorrect.");
}
HttpSession session = request.getSession();
session.setAttribute("login-userId", user.getId());
}
}
회고
DB에 비밀번호가 평문으로 저장되면, 개발자나 해커가 DB에 접속만 할 수 있다면 사용자의 비밀번호는 그대로 노출이되기 때문에 이전 프로젝트에서 의문점을 갖고있었습니다. 그래서 이번에 해시 알고리즘을 통해 비밀번호를 암호화하는 과정을 거치면서 의문점이 해결되었습니다.
'Project' 카테고리의 다른 글
[Project] Lv_7 스케줄 프로젝트(심화) (0) | 2025.05.23 |
---|---|
[Project] Lv_5 스케줄 프로젝트(심화) (0) | 2025.05.22 |
[Project] Lv_4 스케줄 프로젝트(심화) (0) | 2025.05.21 |
[Project] Lv_3 스케줄 프로젝트(심화) (0) | 2025.05.20 |
[Project] Lv_2 스케줄 프로젝트(심화) (0) | 2025.05.20 |