일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 세그먼트 트리
- ddd
- 데이터 flow
- springboot
- DP
- 비트마스크
- docker
- spring security
- BFS
- 파이썬
- 위상정렬
- java
- pandas
- 백준
- JPA
- Redis
- 스프링
- 자바
- 다익스트라
- series
- equals
- 헥사고날 아키텍처
- 포트앤어댑터 아키텍처
- 이펙티브 자바
- UML
- 문자열
- 알고리즘
- disjoint set
- dfs
- dataframe
Archives
- Today
- Total
코딩못하는사람
BCryptPasswordEncoder 패스워드 암호화 관련 이슈 본문
문제점
스프링 시큐리티를 활용하기 위해서는 DB에 해쉬로 암호화된 패스워드를 저장해야 한다.
따라서 BCryptPasswordEncoder에 encode 메서드를 통해 해쉬암호화를 사용하여 패스워드를 저장했다.
문제는 패스워드 변경 관련 로직 및 테스트 코드 작성에서 발생했다.
@Test
public void 회원정보_업데이트_테스트() throws Exception {
//given
User user = userRepository.findByName("test").orElseThrow(NoSuchUserException::new);
UpdatePasswordDTO updatePasswordDTO = new UpdatePasswordDTO("12345", "1234", "1234");
//when
userService.updateName(updateNameDto,user.getId());
userService.updatePassword(updatePasswordDTO, user.getId());
//then
assertThat(bCryptPasswordEncoder.encode("1234")).isEqualTo(user.getPassword());
}
기존 회원의 패스워드를 변경하고 잘 변경되었는지 확인하는 테스트 코드이다.
비밀번호를 "12345"->"1234"로 변경하고 junit을 활용하여 확인해보았지만 계속 실패했다.
원인
원인을 파악하기 위해 여러가지를 찍어보던중 해쉬로 encode되는 값이 매번 달라지는 것을 알아냈다.
System.out.println(result.getPassword());
System.out.println(bCryptPasswordEncoder.encode("12345"));
같아야 하는 값이 계속 다르게 출력되고 있었다. 그래서 BCrypt에 대해서 조사해봤다.
BCrypt는 해쉬에 솔트를 더하여 매번 다르게 값이 출력되게 만들어서 보안을 더 높인 암호화 방식이다.
따라서 솔트가 매번 다르기 때문에 encode된 값과 equals로 비교가 항상 다르기 때문에 테스트가 통과될 수 없는 구조였다. 해쉬를 하면 매번 같은 값이 나올것이라는 착각이였다.
해결방법
equals로 비교할 수 없는 BCryptPasswordEncoder은 비교 메서드 matches를 제공한다.
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (rawPassword == null) {
throw new IllegalArgumentException("rawPassword cannot be null");
} else if (encodedPassword != null && encodedPassword.length() != 0) {
if (!this.BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
this.logger.warn("Encoded password does not look like BCrypt");
return false;
} else {
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
} else {
this.logger.warn("Empty encoded password");
return false;
}
}
따라서 테스트 코드를 다음과 같이 짜주면 해결할 수 있다.
assertThat(bCryptPasswordEncoder.matches("1234", result.getPassword())).isEqualTo(true);
assertThat(bCryptPasswordEncoder.matches("12345", result.getPassword())).isEqualTo(false);
배운점
- 해쉬를 한번 더 공부하게 되었다.
- 사용하는 기능에 대해서 잘 모르고 사용하는게 위험하다는 것을 또 느꼈다. 항상 제대로 알고 사용하자
'issue 기록' 카테고리의 다른 글
Nginx 헬스 체크 (0) | 2022.01.05 |
---|---|
JPA/ could not initialize proxy - no Session (9) | 2021.09.14 |
JPA delete관련 에러 (Cascade 영속성 전이 관련 에러) (3) | 2021.08.19 |
@AllArgsConstructor,@NoArgsConstructor (0) | 2021.06.05 |
JPA 중복 칼럼 에러 (0) | 2021.04.18 |
Comments