[Spring] 비밀번호 암호화 - Bcrypt를 위한 스프링 시큐리티 모듈

2022. 11. 18. 15:23·📗 self-study/📗 KH정보교육원 당산지원

⌛️ 현재 상황

DB에 사용자의 비밀번호가 그대로 노출되는 것은

 

🚨 불법입니다 🚨

 

암호화해야 함!

 

현재 비밀번호가 사용자가 입력한 그대로의 평문임
사람이 그냥 눈으로 의미를 파악할 수 있는 데이터: 평문
사람이 그냥 눈으로 의미를 파악할 수 없게 처리한 데이터: 암호문

👉🏻  스프링에서 제공하는 Bcrypt 방식으로 비밀번호를 암호화 할 것

 

 

 

암호화 적용하는 법

  
1) 스프링 시큐리티 모듈에서 제공하는 라이브러리를 추가 (Maven)

스프링 시큐리티 모듈 라이브러리들 (core, web, config)의 버전을 모두 일치시켜야 함

 

https://mvnrepository.com/

 

👉🏻  3개 모두 다운로드받아야 함

 

👉🏻  Usages가 높은 5.7.3으로 통일하려 함

 

💻 pom.xml

		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-core</artifactId>
		    <version>5.7.3</version>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-web</artifactId>
		    <version>5.7.3</version>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-config</artifactId>
		    <version>5.7.3</version>
		</dependency>

👉🏻 다운로드 완료 확인!

 

2) BCryptPasswordEncoder 클래스를 xml 파일에 bean으로 등록

👉🏻 암호화 파일의 경우 이렇게 따로 빼 두는 추세임

 

webapp/WEB-INF/spring 폴더 내부에 Spring Bean Configuration File 생성

 

 

 

💻 spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="bcryptPasswordEncoder" />
	
</beans>

 

3)web.xml에 spring-security.xml 파일을 로딩할 수 있게 등록

💻 web.xml

👉🏻 <param-value>에 추가해 주기

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring/root-context.xml
			/WEB-INF/spring/spring-security.xml // 이 부분 추가함
		</param-value>
	</context-param>

 

💻 MemberController에 변수 생성

👉🏻 위치 확인하려고 위/아래 코드 함께 기재하였으나 실제로 추가한 것은 @Autowired 어노테이션과 bcryptPasswordEncoder 변수뿐임!

@Controller
public class MemberController {

	// 스프링 방식
	@Autowired // @Autowired 어노테이션 기재해 주고
	private MemberService memberService; // 선언만 해 주면 됨!
	
	// 비밀번호 암호화를 위한 변수
	@Autowired
	private BCryptPasswordEncoder bcryptPasswordEncoder; // 어노테이션과 이 줄만 추가해 줌!

 

💻 출력 테스트

package com.kh.spring.member.controller;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.kh.spring.member.model.service.MemberService;
import com.kh.spring.member.model.vo.Member;


@Controller
public class MemberController {
	
	// 스프링 방식
	@Autowired // @Autowired 어노테이션 기재해 주고
	private MemberService memberService; // 선언만 해 주면 됨!
	
	// 비밀번호 암호화를 위한 변수
	@Autowired
	private BCryptPasswordEncoder bcryptPasswordEncoder;
	
	@RequestMapping("insert.me")
	public void insertMember(Member m) {
		
		System.out.println(m);
		
		System.out.println("평문: " + m.getUserPwd());
		
		// 암호화 작업 (암호문을 만들어 내는 과정)
		String encPwd = bcryptPasswordEncoder.encode(m.getUserPwd());
		System.out.println("암호문: " + encPwd);
		
	}
	
}

👉🏻 같은 평문이어도 매번 다른 암호문 결과가 나옴
👉🏻 평문 + salt(랜덤값)을 한 암호화 작업이 이루어지기 때문

 

 

 

📍 하지만, 현재의 문제점!

일치하는 정보를 입력했음에도

 

 로그인이 되지 않는다!

 

👉🏻 현재 로직상 평문으로 비교를 하기 때문에 당연히 암호문으로 저장된 DB의 내용과 일치하지 않음!

👉🏻 해당 로직 모두 주석 처리 (MemberControllerdml loginMember 메소드)

 

💻 member-mapper.xml

👉🏻 현재의 조건은 USER_PWD(DB 컬럼명, 암호문) = #{userId}(필드명, 평문)이기 때문에 애초에 일치할 수가 없음!

👉🏻 암호화 작업 후: 매번 암호문이 다르게 나오기 때문에 비밀번호 관련 일치 조건을 기술 불가
👉🏻 오로지 아이디만으로 회원을 조회할 것 (어차피 PK니까!) 

	<!-- 로그인용 쿼리문 -->
	<select id="loginMember" parameterType="member" resultMap="memberResultSet">		
		SELECT *
		FROM MEMBER
		WHERE USER_ID = #{userId}
		AND STATUS = 'Y'
	</select>

 

💻 MemberController

👉🏻 BCrypt 방식에 의해 복호화가 불가능한 암호문 형태의 비밀번호와 일치하는지 대조 작업
💡 Member m의 userId 필드: 사용자가 입력한 아이디 (평문)
💡                            userPwd 필드: 사용자가 입력한 비밀번호 (평문)

 

👉🏻 loginUser: 오로지 아이디만 가지고 조회된 회원의 정보
👉🏻 Member loginUser의 userPwd 필드: DB에 기록된 암호화된 비밀번호
💡 일치하는 아이디 기준으로 모든 컬럼을 가지고 왔으므로 현재 DB에서 가지고 온 정보에는 "암호화된 비밀번호"가 들어 있음

	
	@RequestMapping("login.me")
	public ModelAndView loginMember(Member m, ModelAndView mv, HttpSession session) {
		
		// 암호화 작업 후 로직
		Member loginUser = memberService.loginMember(m); // 그대로 호출

		if(loginUser != null &&
				bcryptPasswordEncoder.matches(m.getUserPwd(), loginUser.getUserPwd())) {
			
			// 비밀번호도 일치한다면 => 로그인 성공
			session.setAttribute("loginUser", loginUser);
			session.setAttribute("alertMsg", "로그인에 성공했습니다.");
			
			mv.setViewName("redirect:/");
			
		} else { // 일치하지 않는다면 => 로그인 실패
			
			mv.addObject("errorMsg", "로그인 실패");
			
			// /WEB-INF/views/common/errorPage.jsp
			mv.setViewName("common/errorPage");
		}
		
		return mv;
	}

 

 

 

BCryptPasswordEncoder 객체의 matches 메소드

matches(평문, 암호문) 을 작성하면 내부적으로 평문과 암호문을 맞추는 작업이 이루어짐
👉🏻두 구문이 일치하는지 비교 후 일치하면 true 반환

 

 

 

💻 출력 화면 확인

DB에 있는 아이디를 입력했을 때

 

DB에 없는 아이디를 입력했을 때
DB에 있는 아이디지만 틀린 비번을 입력했을 때

저작자표시 비영리 변경금지 (새창열림)
'📗 self-study/📗 KH정보교육원 당산지원' 카테고리의 다른 글
  • [Spring] Spring 웹 사이트 만들기 5 - 마이페이지(회원 정보 변경, 회원 탈퇴)
  • [Spring] 새로운 라이브러리를 사용하고 싶다면?
  • [Spring] Lombok (롬복) - 코드를 자동으로 생성해 주는 라이브러리
  • [Spring] Spring 웹 사이트 만들기 4 - 회원가입 기능
천재강쥐
천재강쥐
  • 천재강쥐
    디버거도 버거다
    천재강쥐
  • 전체
    오늘
    어제
    • Category (467)
      • 진짜 너무 궁금한데 이걸 나만 몰라...? (0)
      • 💾 Portfolio (2)
      • 🐤 CodingTest (28)
        • Java (20)
        • ᕕ(ꐦ°᷄д°᷅)ᕗ❌ (5)
      • 🚀 from error to study (142)
        • AI (1)
        • Cloud (2)
        • DB (12)
        • Front-End (16)
        • Github (14)
        • Java (39)
        • Mac (7)
        • Normal (29)
        • Server (22)
      • 📘 certificate (44)
        • 📘 리눅스마스터1급 (1)
        • 📘⭕️ 정보처리기사 (40)
        • 📘⭕️ SQLD (3)
      • 📗 self-study (234)
        • 📗 inflearn (35)
        • 📗 생활코딩 (8)
        • 📗 KH정보교육원 당산지원 (190)
      • 🎨 Scoop the others (0)
        • 📖 Peeking into other people.. (0)
        • 🇫🇷 (0)
        • 📘⭕️ 한국사능력검정시험 심화 (11)
        • 오블완 (4)
  • 인기 글

  • hELLO· Designed By정상우.v4.10.1
천재강쥐
[Spring] 비밀번호 암호화 - Bcrypt를 위한 스프링 시큐리티 모듈
상단으로

티스토리툴바