회원 등록 시 '비밀번호'는 사용자가 입력한 문자 그대로 DB 에 안 된다는 사실!!
'정보통신망법, 개인정보보호법' 에 의해 비밀번호는 암호화(Encryption)가 의무!!
예를 들어보겠습니다.
앨리스가 여러분의 사이트에 회원가입을 하며 아이디, 패스워드를 입력하였습니다.
- 아이디: alice
- 패스워드: nobodynobody
아무도 알 수 없기를 바라며 적은 패스워드를 아래와 같이 DB 에 평문 그대로 저장해 두었다고 해보죠.
만약 해커에 의해 회원정보가 갈취당한다면 앨리스의 패스워드는 모두가 알게 됩니다.
꼭 해커 뿐만 아니겠죠.
DB 조회가 가능한 내부 관계자들도 앨리스의 패스워드를 보자마자 영원히 기억해 버릴지도 모릅니다.
그래서 아래와 같이 암호화 후 패스워드 저장이 필요 합니다.
평문 → (암호화 알고리즘) → 암호문
"nobodynobody" → "$2a$10$.."
만약 해커가 DB 에 있는 앨리스의 패스워드 정보를 갈취하더라도 실제 암호를 알 수 없습니다.
그래서 복호화가 불가능한 '일방향' 암호 알고리즘 사용이 필요합니다.
'일방향' 암호 알고리즘
암호화: 평문 → (암호화 알고리즘) → 암호문
복호화: 불가 (암호문 → (암호화 알고리즘) → 평문)
암호화 적용
알고리즘 사용용도는 2가지로 나눌 수 있습니다.
1. 회원 가입 시 패스워드를 암호화하여 저장 (직접 구현해 줘야 합니다.)
2. 로그인 인증 시 사용 (스프링 시큐리티가 자동으로 가져다 사용해 줍니다.)
저희는 스프링 시큐리티에서 '권고'하고 있는 'BCrypt 해시함수'를 사용해 패스워드를 암호화하여 DB 에 저장하겠습니다.
@Bean
public BCryptPasswordEncoder encodePassword() {
return new BCryptPasswordEncoder();
}
암호화 알고리즘 준비는 완료하였습니다.
사용 방법을 알아보도록 하겠습니다.
우리가 bean으로 등록한 BCryptPasswordEncoder는 PasswordEncoder를 구현한 것입니다.
사용할 때는 passwordEncoder Bean을 들고와 DI를 하면 되겠습니다.
@Service
public class UserService {
private final PasswordEncoder passwordEncoder;
@Autowired
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
DI를 완료하였다면
비밀번호 암호화는 아래와 같이 진행할 수 있습니다.
String password = passwordEncoder.encode(requestDto.getPassword());