기록/BACKEND

[SpringBoot] 비밀번호 암호화하기

5월._. 2022. 7. 23.
728x90

보안을 위해 사용자 비밀번호를 암호화시켜서 DB에 저장하려고 했다.

해시 알고리즘은 임의의 길이의 데이터를 해싱처리 해 고정된 길이의 데이터로 매핑한다. 그러나 원문을 다시 만들어낼 수는 없다. 

따라서 암호 보안에서는 암호를 해시 처리한 후 사용자 ID와 함께 짝을 지어 DB테이블에 보관한다. 로그인 시, 입력한 암호는 해시 처리되어 DB 테이블의 해시 처리된 입력값과 비교한다. 두 값이 일치한다면 사용자가 올바른 비밀번호를 입력한 것이다.

출처 : https://www.appsealing.com/kr/%ED%95%B4%EC%8B%B1-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98/

스프링에서는 비밀번호 암호화를 위해 제공하는 라이브러리가 있다. 지금 진행하는 프로젝트에서는 springboot를 사용하고 있으므로 이 라이브러리를 활용하기로 했다.

 

1. pom.xml

spring boot starter security를 추가한다.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

 

2. SecurityConfig

1.  클래스 위에 @Configuration, @EnableWebSecurity를 작성한다.

2.  PasswordEncoder Bean을 만든다.

3.  이전 버전에는 WebSecurityConfigurerAdapter를 상속받아서 configure 메서드를 오버라이딩했지만 그 방식은 더 이상 사용되지 않는다. 따라서 SecurityFilterChain Bean을 만든다. cors, csrf를 방지하고 기본 로그인 페이지를 없앴다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	@Bean
	public PasswordEncoder getPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.cors().disable()			//cors 방지
			.csrf().disable()			//csrf 방지
			.formLogin().disable()		//기본 로그인페이지 없애기
			.headers().frameOptions().disable();

		return http.build();
	}
}

 

3. UserServiceImpl

PasswordEncoder를 의존성 주입받아 사용한다.

1.  로그인 : 사용자가 아이디(=이메일), 비밀번호를 입력하면 userInfo에서 가져온 암호화 비밀번호와 지금 입력받은 비밀번호가 일치하는지 passwordEncoder.matches(암호화텍스트, 입력텍스트)로 확인한다. 일치한다면 dto 비밀번호를 암호화된 비밀번호로 변경하고 로그인한다.

2.  회원가입 : 사용자가 입력한 비밀번호를 인코딩한 후 dto 비밀번호 정보를 변경한다. 그 뒤 회원가입한다.

3.  정보 수정 : 사용자가 비밀번호를 변경하고자 한다면(userpw != null) 새 비밀번호를 인코딩한 뒤 dto 비밀번호 정보를 변경한다. 그 뒤 정보수정을 진행한다.

@Autowired
private PasswordEncoder passwordEncoder;

//생략

@Override
public User login(User userDto) throws Exception {
	if(userDto.getUseremail() == null || userDto.getUserpw() == null)
		return null;
	return userMapper.login(userDto);
	//userInfo에서 가져온 비밀번호(암호화됨)와 지금 입력받은 비밀번호 match 확인
	String encodePw = userMapper.userInfo(userDto.getUseremail()).getUserpw();
	if(passwordEncoder.matches(userDto.getUserpw(),encodePw)) {
		//암호화 된 비밀번호로 pw 정보 변경 후 로그인
		userDto.setUserpw(encodePw);
		return userMapper.login(userDto);
	}else {
		return null;
	}
}

@Override
public int register(User userDto) throws Exception {
	//비밀번호 인코딩 후 회원가입
	userDto.setUserpw(passwordEncoder.encode(userDto.getUserpw()));
	return userMapper.register(userDto);
}

@Override
public int modify(User userDto) throws Exception {
	//dto 비밀번호가 null값이 아니라면 인코딩해서 새로 저장
	if(userDto.getUserpw() != null) userDto.setUserpw(passwordEncoder.encode(userDto.getUserpw()));
	return userMapper.modify(userDto);
}

댓글