일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 로그아웃 기능 구현
- 스프링 프로젝트 설정
- 스프링 HikariCP
- 스프링 메일 전송
- 스프링 쇼핑몰
- 스프링 프로젝트
- 쇼핑몰 프로젝트
- spring 쇼핑몰
- 회원가입 기능
- arraylist
- BCrypt 적용
- ResponseEntity
- 쇼핑몰 포트폴리오
- 삭제 구현
- 스프링 프로젝트 기본 설정
- 정규표현식
- 파일 업로드
- 인증번호 전송
- 이미지 출력
- oracle 설치방법
- 스프링 게시판 구현
- 스프링 포트폴리오
- 스프링 이미지
- 스프링 파일 삭제
- 로그인 기능
- 스프링 게시판
- Bcrypt
- spring 프로젝트
- 스프링 업로드
- 스프링 쇼핑몰 프로젝트
- Today
- Total
Kim VamPa
[Spring][Spring Security]BCryptPasswordEncoder란? 본문
목표
- BCryptPasswordEncoder가 무엇인지 이해합니다.
- BCryptPasswordEncoder의 메서드 구성을 공부합니다.
- BCryptPasswordEncoder의 메서드를 직접 사용해봅니다.
순서
1. BCryptPasswordEncoder란?
2. BCryptPasswordEncoder 메서드 구성
3. BCryptPasswordEncoder 사용방법
4. 실습
1. BCryptPasswordEncoder란?
스프링 시큐리티(Spring Seurity) 프레임워크에서 제공하는 클래스 중 하나로 비밀번호를 암호화하는 데 사용할 수 있는 메서드를 가진 클래스입니다.
스프링 시큐리티(Spring Security)란 자바 서버 개발을 위해 필요로 한 인증, 권한 부여 및 기타 보안 기능을 제공하는 프레임워크(클래스와 인터페이스 모임)입니다.
- BCryptPasswordEncoder는 BCrypt 해싱 함수(BCrypt hashing function)를 사용해서 비밀번호를 인코딩해주는 메서드와 사용자의 의해 제출된 비밀번호와 저장소에 저장되어 있는 비밀번호의 일치 여부를 확인해주는 메서드를 제공합니다.
- PasswordEncoder 인터페이스를 구현한 클래스입니다.
- 생성자의 인자 값(verstion, strength, SecureRandom instance)을 통해서 해시의 강도를 조절할 수 있습니다.
BCryptPasswordEncoder는 위에서 언급했듯이 비밀번호를 암호화하는 데 사용할 수 있는 메서드를 제공합니다. 기본적으로 웹 개발함에 있어서 사용자의 비밀번호를 데이터베이스에 저장하게 됩니다. 허가되지 않은 사용자가 접근하지 못하도록 기본적인 보안이 되어 있을 것입니다. 하지만 기본적 보안이 되어 있더라도, 만약 그 보안이 뚫리게 된다면 비밀번호 데이터는 무방비하게 노출됩니다. 이런 경우를 대비해 BCryptPasswordEncoder에서 제공하는 메서드를 활용하여 비밀번호를 암호화 함으로써 비밀번호 데이터가 노출되더라도 확인하기 어렵도록 만들어 줄 수 있습니다.
2. 메서드 구성
BCryptPasswordEncoder는 스프링 시큐리티 5.4.2부터는 3개의 메서드, 그 이전 버전은 2개의 메서드를 가집니다. 공통적으로 encdoe(), matchers() 메서드에 upgradeEncoding() 메서드가 추가되었습니다.
encode(java.lang.CharSequence rawPassword)
- 패스워드를 암호화해주는 메서드입니다. encde() 메서드는 SHA-1, 8바이트로 결합된 해쉬, 랜덤 하게 생성된 솔트(salt)를 지원합니다.
- 매개변수는 java.lang.CharSequence타입의 데이터를 입력해주면 됩니다. (CharSequence를 구현하고 있는 java.lang의 클래스는 String, StringBuffer, StringBuilder가 있습니다.)
- 반환 타입은 String 타입입니다.
- 똑같은 비밀번호를 해당 메서드를 통하여 인코딩하더라도 매번 다른 인코딩 된 문자열을 반환합니다.
matchers(java.lang.CharSequence rawPassword, java.lang.String encodePassword)
- 제출된 인코딩 되지 않은 패스워드(일치 여부를 확인하고자 하는 패스워드)와 인코딩 된 패스워드의 일치 여부를 확인해줍니다.
- 첫 번째 매개변수는 일치 여부를 확인하고자 하는 인코딩 되지 않은 패스워드를 두 번째 매개변수는 인코딩 된 패스워드를 입력합니다.
- 반환 타입은 boolean입니다.
upgradeEncoding(java.lang.String encodePassword)
- 더 나은 보안을 위해서 인코딩 된 암호를 다시 한번 더 인코딩해야 하는 경우에 사용합니다.
- 매개변수는 인코딩 필요 여부를 확인하고자 하는 인코딩 된 패스워드(String 타입)를 입력합니다.
- 반환 타입은 인코딩이 필요한 경우 true를, 필요하지 않은 경우는 false를 입력합니다.
- 기본 구현에는 항상 flase를 반환합니다.
- encde() 메서드를 통해서 암 호환된 패스워드들은 upgradeEncoding()을 사용했을 때 모드 기본적으로 false를 반환합니다.
- 따라서 개인적으로 생각해보았을 때 해당 메서드는 오버라이딩하여 더 강력한 해시를 해야 할지의 기준을 정한 뒤 로직 처리하여 활용할 수 있을 거 같습니다.
3. 사용방법
스프링 시큐리티의 클래스 중 하나이기 때문에 스프링 시큐리티 라이브러리 추가와 기본적 설정이 필요합니다. 전체적인 과정은 다음과 같습니다.
1. 스프링 시큐리티 pom.xml 추가
2. 스프링 시큐리티 기본 설정(web.xml 설정, securi-context.xml 파일 추가 및 BCryptPasswordEncoder 빈 등록)
1. 스프링 시큐리티 pom.xml 추가
pom.xml에 아래와 같이 3가지를 추가해줍니다. 버전의 경우 자신이 원하는 버전을 입력하시면 됩니다. (저의 경우 upgradeEncdoding() 메서드를 사용해보고 싶어서 5.4.2로 설정하였습니다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<!-- security -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.4.2</version>
</dependency>
|
cs |
2. 스프링 시큐리티 기본 설정
기존에 있던 servlet-context.xml에 security namespace를 추가하여 설정해도 됩니다. 하지만 spring security와 관련된 빈과 설정을 따로 관리하기 위해서 security-context.xml 파일을 새로 만들어서 설정하겠습니다.
먼저 servlet-context.xml파일이 있는 경로에 'Spring Bean Configuration File'을 통해서 'security-context'이름의 파일을 'benas'와 'security' namespaces를 추가 해준 뒤 생성합니다.
* security namespace의 경우 버전이 적히지 않은 것을 선택해줍니다.
생성한 파일에 BCryptPasswordEncoder를 빈으로 등록하기 위해 아래의 코드를 추가해줍니다.
1
2
3
|
<bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
|
cs |
web.xml에서 servlet-context.xml의 경로가 적힌 태그 안에 줄 바꿈을 하여 동일하게 Security-context.xml파일의 위치를 삽입해줍니다. 해당 과정을 생략하면 스프링에서 security-context.xml을 인식하지 못합니다.
이로써 BCryptPasswordEncoder를 사용하기 위한 기본적인 설정이 끝났습니다.
4. 실습
위의 설정을 바탕으로 BCryptPasswordEncoder의 메서드를 직접 사용해보겠습니다. MVC 웹 프로젝트를 처음 생성했을 때 기본적으로 존재하는 HomeController.java를 활용하겠습니다.
먼저 @Autowired를 사용해서 BCryptPasswordEncoder를 의존성 주입시켜줍니다.
1
2
3
4
|
@Autowired
BCryptPasswordEncoder passwordEncoder;
|
security 메서드만을 테스트하기 위한 url 맵핑 메서드를 추가하였습니다.
1
2
3
4
5
6
7
|
@RequestMapping(value = "/secuTest", method = RequestMethod.GET)
public void secuTest() {
}
|
cs |
아래와 같이 테스트를 위한 코드를 추가하였습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@RequestMapping(value = "/secuTest", method = RequestMethod.GET)
public void secuTest() {
String rawPassword = "vam123"; //인코딩 전 메서드
String encdoePassword1; // 인코딩된 메서드
String encdoePassword2; // 똑같은 비밀번호 데이터를 encdoe()메서드를 사용했을 때 동일한 인코딩된 값이 나오는지 확인하기 위해 추가
encdoePassword1 = passwordEncoder.encode(rawPassword);
encdoePassword2 = passwordEncoder.encode(rawPassword);
// 인코딩된 패스워드 출력
System.out.println("encdoePassword1 : " +encdoePassword1);
System.out.println(" encdoePassword2 : " + encdoePassword2);
String truePassowrd = "vam123";
String falsePassword = "asdfjlasf";
System.out.println("truePassword verify : " + passwordEncoder.matches(truePassowrd, encdoePassword1));
System.out.println("falsePassword verify : " + passwordEncoder.matches(falsePassword, encdoePassword1));
}
|
cs |
서버를 실행하여 해당 url 메서드를 호출한 결과입니다.
결과를 보면 분명 같은 rawPassword 변수의 값을 endcode() 메서드를 사용하여 인코딩하였음에도 서로 다른 값이 반환 된 것을 볼 수 있습니다.(encodePassword1!= encdoePassword2)
truePassword 변수에는 일치하는 값을 대입하였고, falsePassword 변수에는 일치하지 않는 값을 대입하였습니다. 해당 변수들을 사용해서 인코딩 된 비밀번호와의 일치 여부를 확인하기 위해서 matches() 메서드를 활용하였고 그 결과로 일치하는 값을 가진 truePassword 변수를 사용했을 경우에는 true를, 일치하지 않는 값을 가진 falsePassword 변수를 사용했을 경우는 false를 반환한 것을 알 수 있습니다.
REFERENCE
- ko.wikipedia.org/wiki/%ED%95%B4%EC%8B%9C_%ED%95%A8%EC%88%98
- docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html
- docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/password/PasswordEncoder.html
- ko.wikipedia.org/wiki/SHA
- en.wikipedia.org/wiki/Bcrypt
DATE
- 2021.01.18
'공부 > 스프링' 카테고리의 다른 글
[spring] Spring Interceptor 란?(HandlerInterceptor, HandlerInterceptorAdapter) (5) | 2021.01.13 |
---|---|
[Spring]메일서버(SMTP Server)를 이용한 메일 전송 2 (8) | 2020.08.28 |
[Spring]메일서버(SMTP Server)를 이용한 메일 전송 1 (7) | 2020.08.27 |
[Spring][06] Log4jdbc-log4j2 추가 및 설정방법 (2) | 2020.04.14 |
[Spring][05-2]MyBatis 사용(Mapper 인터페이스, Mapper XML) (6) | 2020.04.13 |