냐냐한 IT/냐냐한 Spring Boot

BCryptPasswordEncoder 사용, 암호화 및 암호 확인 (Spring Boot)

소소하냐 2023. 2. 7. 11:03

비밀번호를 암호화하는 기능을 추가하려고 합니다. 

로그인 등 인증 기능은 현재 필요하지 않습니다. 

 

spring-boot-starter-security 를 추가하여, BCryptPasswordEncoder를 사용해 암호화를 진행하려고 합니다. 

 

1. build.gradle에 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-security'

 

위 라이브러리를 추가 후, 실행해보면 어떤 페이지로 이동하든 로그인 페이지로 리다이렉트됩니다. 

 

로그인 페이지로 리다이렉트

 

2. 로그인 페이지로 이동하게 하는 보안 구성 끄기 

(보안 구성이 필요하다면, 이 부분은 무시하셔도 좋습니다. )

 

암호화만 이용할 생각이기 때문에, 로그인 페이지로 이동하게 하는 보안 구성이 필요없습니다. 

해당 구성이 동작하지 않도록 코드를 수정합니다. 

 

main 메서드가 있는 xxxApplication 클래스의, @SpringBootApplication 어노테이션에 (exclude={SecurityAutoConfiguration.class})를 추가합니다. 

@SpringBootApplication(exclude={SecurityAutoConfiguration.class})
public class SiteApplication {

    public static void main(String[] args) {
        SpringApplication.run(SiteApplication.class, args);
    }

}

 

3. 비밀번호 암호화 

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

// 생략... 
private String password;
public void setPassword(String password) {
    this.password = password;

    // 입력된 비밀번호 암호화하기
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    this.password = encoder.encode(password);
}

 

4. 비밀번호가 일치하는지 확인 

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@PostMapping("/api/{id}/contents")
public ResultAPI getContents(@PathVariable("id") Long id, @RequestBody Map<String, String> param){

    String password = param.get("password"); // 사용자가 입력한 비밀번호
    
    // 비밀번호 확인 하기
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    if(encoder.matches(password, shareText.getPassword())){
        // 비밀번호 확인 성공             
    } else {
        // 비밀번호 일치 하지 않음 
    }
}

 

!주의! 

  • BCryptPasswordEncoder는 salt값을 사용하기 때문에, 같은 비밀번호라도 항상 다른 암호화 결과값이 나옵니다. 
  • 그런 이유로, == 또는 equal 로 체크하면 아무리 맞는 비밀번호를 입력하여도 비밀번호가 일치하지 않는다고 합니다. encoder.matches를 이용하세요. 
if(encoder.matches(password, shareText.getPassword())){
    // 이렇게 사용해야 합니다.
}

/* 
if(shareText.getPassword().equals(encodePassword)){
    // 이렇게 쓰면 안됩니다. 
}
*/

 


오류 발생 및 해결

 

build.gradle에 아래 의존성을 추가한 후, 암호화 하는 코드(BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();)에서 오류가 발생했습니다.  

 

오류 내용은 아래와 같습니다: 

java.lang.ClassNotFoundException: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]

java.lang.ClassNotFoundException: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder

 

왜, 클래스를 못 찾을까요... 분명 있는데...

검색을 하니, 대부분 버전이 일치하지 않아서 그렇다고 합니다. 하지만 저는 그 문제가 아니었습니다. 

 

어의없는 이유였습니다. 

 

이미 실행(Run)중인 상태에서, spring-boot-devtools로 인해 자동 빌드 및 Server Restart 된 상태에서 해당 코드가 호출되면 발생하는 오류였습니다. 

 

build.gradle에 라이브러리를 추가하면, 수동으로 꼭 재실행해주는 것으로!

(저는 이 문제로 3시간 이상 날려먹은 듯 하네요...)

 

끝까지 읽어주셔서 감사합니다.