| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- opc-ua 다운로드
- prosys opc-ua
- 컴퓨터과학
- C#이론
- 스프링부트의 장단점
- 스프링 스프링부트 차이점 공통점
- REST API
- nosql
- 스프링부트회원가입
- 스프링부트 단점
- Blazor WebAssembly
- java란?
- OPC-UA Download
- Prosys Opc-ua 다운로드
- java란 무엇인가
- 기술면접
- 스프링부트로그인
- Service Worker
- 스프링부트 장점
- UaExpert download
- Blazor Web App
- cs기술면접
- UaExpert다운로드
- C# Blazor
- spring spring boot 차이점 공통점
- jvm구성요소
- C# CS
- CS
- OPC-UA
- 프론트엔드
- Today
- Total
담비의 개발블로그
[Spring Boot]PasswordEncoder 본문
PasswordEncoder
PasswordEncoder는 단방향 해싱과 솔팅을 사용한다.
◆ 단방향 해싱 (One-Way Hashing)
해싱은 입력된 원본 값을 기반으로 복잡한 계산을 거쳐 고정된 길이의 문자열(해시)을 만든다.
만약 사용자가 "1234"라는 비밀번호로 회원가입을 할 때, DB에 "1234"라고 그대로 저장했다고 가정해보자.
이때 DB가 해킹당하게 된다면 해커가 모든 회원의 아이디와 비밀번호 "1234"를 알아내게 된다. 이 문제를 해결하기 위해, "1234"를 아무도 알아볼 수 없는 복잡한 문자열(예: $2a$10$N9qo8uLO...)로 변환해서 저장한다. 이 '변환'을 해싱(Hashing)이라고 부르며, 이 역할을 하는 도구가 바로 PasswordEncoder이다.
◆ 솔팅 (Salting)
솔팅은 원본 비밀번호에 '소금(Salt)'처럼 임의의 랜덤 값을 추가하여 해싱하는 기법이다.
해싱은 동일한 입력값에 대해 항상 동일한 출력값을 반환한다. (예: 1234 -> abcd) 만약 해커가 미리 계산된 해시 값들의 목록(레인보우 테이블)을 가지고 있다면, 저장된 해시 값을 비교하여 원본 비밀번호를 유추할 수 있다.
예시:
(Bad) 1234 -> abcd
(Good) 1234 + random_salt_1 -> zxyw
(Good) 1234 + random_salt_2 -> qwer (다른 사용자가 같은 비번을 써도 다르게 저장됨)
BCrypt와 같은 최신 인코더는 이 Salt 값을 해시 결과물에 자동으로 포함시켜 관리하므로 개발자가 솔트를 별도로 저장할 필요가 없다.
◆ PasswordEncoder의 핵심 메서드
1. String encode(CharSequence rawPassword)
회원가입시 사용된다. 사용자가 입력한 원본 비밀번호(rawPassword)를 받아, 솔팅(Salting) 및 해싱(Hashing)을 수행한 후, 암호화된 문자열을 반환한다. 이 값을 DB에 저장한다.
2. boolean matches(CharSequence rawPassword, String encodedPassword)
로그인 시 사용된다. 사용자가 로그인 시 입력한 원본 비밀번호(rawPassword)와 DB에 저장된 해시된 비밀번호(encodedPassword)를 비교한다. (이 메서드는 encodedPassword를 복호화하는 것이 아니다.)
encodedPassword에서 Salt 값을 추출한다. rawPassword에 그 Salt 값을 더해 다시 해싱한다. 그 결과가 encodedPassword와 일치하는지 비교하여 true / false를 반환한다.
◆ 스프링 부트에서 사용하기
스프링 시큐리티에서는 BCryptPasswordEncoder를 가장 널리 권장한다. BCrypt는 비밀번호 해싱을 위해 설계된 검증된 알고리즘이며, 자동으로 솔팅을 처리해 준다.
1. html 코드
<form th:action="@{/login-process}" method="post">
<div>
<label>아이디:</label>
<input type="text" name="username"> </div>
<div>
<label>비밀번호:</label>
<input type="password" name="password"> </div>
<button type="submit">로그인</button>
</form>
2. Controller 코드
@Controller
public class PageController {
// 1. 로그인 '페이지' 보여주기 (GET)
@GetMapping("/login")
public String showLoginPage() {
return "login"; // login.html
}
// 2. 로그인 '처리' (POST)
// ... 가 없음!!!!
// @PostMapping("/login-process") 같은 코드를 만들지 않음!!
}
3. SecurityConfig
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
// UserDetailsServiceImpl을 주입받는다.
private final UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/login", "/register").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
// 1. 로그인 페이지 주소 (PageController의 @GetMapping)
.loginPage("/login")
// 2. [!! 여기가 핵심 !!]
// HTML의 <form action="/login-process">가
// 'POST'로 요청을 보내면,
// 스프링 시큐리티가 이 요청을 "가로채서" 알아서 처리한다.
.loginProcessingUrl("/login-process")
// 3. 로그인 성공 시 이동할 곳
.defaultSuccessUrl("/", true)
.permitAll()
);
return http.build();
}
}
4. LoginService 대신 UserDetailsServiceImpl
@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserRepository userRepository;
// (PasswordEncoder가 여기엔 없ek!)
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 4. 스프링 시큐리티가 ID만 넘겨주면서 "사용자 정보 줘"라고 호출
UserEntity user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("..."));
// 5. DB의 '암호화된 비번'을 그대로 전달
return new User(user.getUsername(), user.getPassword(), ...);
}
}
'언어&프레임워크 > Spring&Spring Boot' 카테고리의 다른 글
| int integer 차이 (0) | 2025.02.26 |
|---|---|
| [Spring Boot]이클립스 FAILURE: Build failed with an exception. 오류 (1) | 2024.12.09 |
| [Spring Boot]Security (1) | 2024.10.02 |
| [Spring Boot]Pagination (1) | 2024.09.26 |
| [Spring Boot]구글 리캡차 사용법 (1) | 2024.08.19 |