이전에는 sha 방식의 암호화를 사용했었는데, sha 방식 암호화는 같은 비밀번호를 입력하면 똑같이 암호화가 됐었다.
ex) [회원1] pw(평문):1234 -> 암호:abcd / [회원2] pw(평문):1234 -> 암호:abcd
== 단방향 암호화에 사용되는 해시 알고리즘은 동일한 평문에 대해 항상 동일 해시값을 갖는다. 따라서 특정 해시 알고리즘에 대하여 특정 평문이 어떤 해시값을 갖는지 알 수 있다.
이러한 문제를 보안하기 위해 단방향 암호화를 진행할 때 솔팅(Salting)과 키 스트레칭(Key Stretching)을 적용 시킨 Bcrypt를 사용한다!
Bcrypt 또한 단방향 해시 알고리즘이다. 하지만, 매번 암호화되는 비밀번호가 달라져서 DB에서 직접 비교가 불가능하다. 대신 Bcrypt 암호화를 지원하는 객체가 이를 비교하는 기능(메소드)를 가지고 있어서 이를 활용할 수 있다. Bcrypt의 검증은 암호화된 값이 가지고 있는 알고리즘, Cost Factor, Salt를 이용한다.
✔️ 솔팅(Salting)
솔팅은 단방향 해시 함수 암호화를 진행 할 때 본래 데이터에 추가적으로 랜덤한 데이터를 더하는 방식이다. 원래 데이터에 추가 데이터가 포함 되었기 때문에 이전의 해시값과 달라진다.
✔️ 키 스트레칭(Key Stretching)
단방향 해쉬값을 계산 한 후, 그 해쉬값을 또 다시 해시하고 또 이를 반복하는 방식이다.
Bcrypt 암호화를 사용하기 위해 이를 지원하는 Spring-security 모듈 추가 -> pom.xml
Maven에서 5.7.1 버전
- Spring Security Core
- Spring Security Web
- Spring Security Config
src/main/resources/spring > "spring-security.xml" 추가
-> xml 파일 XX -> spring > Spring Bean Definition file > 이름: spring-security.xml > security 체크 > next > finish
Bcrypt 암호화용 bean 생성
<bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/root-context.xml
classpath:spring/spring-security.xml
</param-value>
</context-param>
// 암호화를 위한 bcrypt 객체 의존성 주입(DI)
@Autowired
private BCryptPasswordEncoder bcrypt;
// 비밀번호 암호화
bcrypt.encode(inputMember.getMemberPw())
// 암호화된 비밀번호와 평문 비밀번호 비교
if(loginMember != null) { //일치하는 이메일을 가진 회원 정보가 있을 경우
// =입력된 비밀번호(평문) , 조회된 비밀번호(암호화) 비교 => 같으면 true
if(bcrypt.matches(inputMember.getMemberPw(), loginMember.getMemberPw())) { // 비밀번호가 일치할 경우
loginMember.setMemberPw(null); // 비교 끝났으면 비밀번호 지우기
// 비밀번호 세션에 넘어가지 않도록 무효처리
}else { // 비밀번호가 일치하지 않을 경우
loginMember = null;
}
}