국비 64 - 필터_암호화

냐아암·2023년 8월 7일
0

국비

목록 보기
80/114
package edu.kh.community.common.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;

import edu.kh.community.common.wrapper.EncryptWrapper;

// 암호화를 적용해야되는 요청 : 로그인, 회원가입, 비밀번호 변경, 회원탈퇴
// 필터가 적용될 url이 여러 개인 경우 : String 배열 초기화 형태 {}로 작성
@WebFilter(filterName="encryptFilter", 
			urlPatterns = {"/member/login", 
							"/member/signUp",
							"/member/myPage/changePw",
							"/member/myPage/secession"})
public class EncryptFilter extends HttpFilter implements Filter {
       
	public void init(FilterConfig fConfig) throws ServletException {}
    
	public void destroy() {}
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		// 비밀번호는 파라미터 -> HttpServletRequest에 담겨 있음
		
		// doFilter 메소드 매개변수는 부모타입인 ServletRequest에 담겨 있다.
		// -> 다운캐스팅 필요
		
		HttpServletRequest req = (HttpServletRequest)request;
		
		//  파라미터를 다시 세팅하는 방법은 필터에서 불가능함
		// -> Servlet의 Wrapper 클래스를 이용해서
		//	  HttpServletRequest의 메소드를 오버라이딩 할 수 있다.
		//	-> 오버라이딩(재정의)을 통해서 비밀번호 암호화 진행
		
		// wrapper 객체를 생성해서 기존 HttpServletRequest 객체 역할 대체
		EncryptWrapper wrapper = new EncryptWrapper(req);
		
		// 다음 연결된 필터 수행(없으면 Servlet으로 이동)
		chain.doFilter(wrapper, response);
	}

	

}
package edu.kh.community.common.wrapper;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class EncryptWrapper extends HttpServletRequestWrapper {


	// HttpServletRequestWrapper
	// - 클라이언트 요청 객체 HttpServletRequest를 오버라이딩 하는 방법을 제공하는 클래스
	
	// 생성자가 작성되어 있으면 
	// 컴파일러가 기본생성자를 자동 추가 안 함
	
	// -> Wrapper 클래스 생성 시 반드시 HttpServletRequest 객체를 매개변수로 전달해야 한다.
	public EncryptWrapper(HttpServletRequest request) {
		super(request);
	}

	// getParameter() 오버라이딩
	@Override
	public String getParameter(String name) {
		
		// 매개변수 name : input태그의 name 속성값
		// super.getParameter(name) : 기존 getParameter() 메소드
		
		String value = null;
		
		switch(name) {
		
		case "inputPw" :
		case "memberPw" :
		case "currentPw" :
		case "newPw" :
			value=getSha512(super.getParameter(name));
			break;
		
		// 암호화되는 경우가 아니라면 기존 getParameter() 메소드 형태 유지
		default : value = super.getParameter(name);
		
		}
		
		return value;
	}
	
	// 암호화 메소드(SHA-512 해시 함수)
	
	// 해시 함수 : 어떤 문자열이든 일정한 길이의 무작위 문자열로 변환하는 함수(중복 X)
	
	private String getSha512(String pw) {
		// 매개변수 pw : 암호화되기 전 비밀번호
		
		String encryptPw = null; // 암호화된 비밀번호 저장 변수
		
		// 1. 해시함수를 수행할 객체를 참조할 변수 선언
		MessageDigest md = null;
		
		try {
			
			// 2. SHA-512 방식의 해시함수를 수행할 수 있는 객체 얻어옴
			md = MessageDigest.getInstance("SHA-512");
			
			// 3. md를 이용해 암호화를 진행할 수 있도록 pw를 byte[]형태로 변환
			byte[] bytes = pw.getBytes(Charset.forName("UTF-8"));
			
			// 4. 암호화 수행 -> 암호화 결과가 me 내부에 저장됨
			md.update(bytes);
			
			// 5. 암호화된 비밀번호를 encryptPw에 대입
			// -> byte[]을 String으로 변환할 필요가 있음
			//    Base64 : byte코드를 문자열로 변환하는 객체
			encryptPw = Base64.getEncoder().encodeToString(md.digest());
			
			System.out.println("암호화 전 : " + pw);
			System.out.println("암호화 후 : " + encryptPw);
			
		} catch (NoSuchAlgorithmException e) {
			// SHA-512 해시 함수가 존재하지 않을 때 예외 발생
			e.printStackTrace();
		}
		
		return encryptPw;
		
	}
	
	
}
profile
개발 일지

0개의 댓글