[Spring] 암호학

김승현·2022년 1월 21일
0

암호학

  • 암호에 관련된 일련의 기술
  • 정보를 보호하기 위한 언어학적 및 수학적 방법론을 다루는 학문

암호학에서 자주 사용되는 용어

  • 평문 : 정보(데이터)를 가지고 있는 원본
  • 암호문 : 내용을 제3자가 판독할 수 없는 글자,숫자,부호 등으로 변경 시킨 것
  • 암호화 : 평문을 암호문으로 변경하는 것
  • 복호화 : 암호문을 평문으로 변경하는 것

암호화의 기본 요소

  • 평문(데이터)

  • 알고리즘(algorithm)

    • 평문을 암호문으로, 암호문을 평문으로 암호/복호화 할때 사용하는 일련의 순차적인 계산법
  • 키(key)

    • 암호화의 임의성을 추가 하기 위한 임의의 값
  • [평문] -> 암호화 알고리즘 + Key -> <암호문>

  • <암호문> -> 복호화 알고리즘 + Key -> [평문]

암호학의 종류

  • 초기 암호학, 현대 암호학
  • 기계(컴퓨터)에 의해 암호화가 수행되기 이전과 이후로 나누어짐

암호 시스템

  • 암호화/복호화에 요구되는 요소들의 결합 방식
  • 알고리즘과 키가 핵심 요소
  • 알고리즘 : 암호화/복호화에 적용된 수학적 원리 및 수행 절차
    • 암호화 알고리즘과 복호화 알고리즘으로 구분
    • 알고리즘은 이해와 구현은 쉬운 대신 공격에는 강해야 함
  • 키(Key) : 암호화/복호화 능력을 얻기 위한 지식 (추가정보)
    • 키는 동일한 알고리즘으로 여러 사용들이 고유하게 활용할 수 있게 해줌

대칭키 암호 시스템

  • 암호화 키와 복호화 키가 같음
  • 비밀키(Secrete key), 관용키 (Conventional key), 단일키(Single key) 시스템이라고도 부름
  • 송신자와 수신자만 사용 가능한 비밀키 사용 시스템
  • 장점 : 대칭키 알고리즘은 비대칭 시스템보다 훨씬 빠른 암복호화가 가능 함
  • 단점 : 키를 안전하게 전달하는 메커니즘이 있어야 함
  • 대칭키 알고리즘의 종류
    • DES
    • AES
    • SEED
    • 등등

비대칭키 암호 시스템

  • 암호화 키와 복호화 키가 다름
  • 공개키 (Public key) 시스템 이라고도 함
  • 각 각의 사용자는 자신만 사용할 수 있는 사설키(Private key)와 누구라도 사용 가능한 공개키(Public key) 쌍을 소유
    • Key가 각 각 2개 라는 의미
    • 공개키를 가지고 사설키를 알아 낼 순 없음
    • 상대방의 공개키로 암호화 하여 전달하면 상대방은 사설키로 복호화하여 내용은 전달 받음
  • 장점 : 대칭키 방식보다 나은 키 분배
  • 단점 : 대칭키 방식보다 암호화/복호화 속도가 느림
  • 비대칭키 알고리즘의 종류
    • Diffie-Helloman
    • RSA
    • ECC
    • 등등

Hash 함수

  • Hash 함수는 단방향 알고리즘
    • 암호화하는 하되, 복호하는 할 필요 없을 때 사용
  • 특징
    • Compression(축약) : 다양한 길이의 입력을 고정길이의 출력으로 축약 하는 함수
    • One-Way(단방향) : 평문을 암호화하여 해시 코드를 구할 수는 있으나, 해시 코드로 평문을 복원할 수 없음
    • 효율성 : 평문에서 암호문(해시값)까지 많은 자원과 시간이 소요되지 않음
    • Collision-free : 메시지가 고유하다면 그에 대한 해시값도 고유하게 나옴
  • 해시 함수 종류
    • MD5
      • 128bit 고정길이 결과값 (16Byte)
    • SHA-1
      • 160bit 고정길이 결과값 (20Byte)
    • SHA-256
      • 256bit 고정길이 결과값 (32Byte)
    • MD5
    • SHA (SHA-1, SHA-128, SHA-256 등등)
    • 등등
  • 암호화 후 복원을 해야 하는 데이터인 경우에는 대칭키/비대칭키 알고리즘을 사용
    • DB에 저장된 개인정보
  • 암호화 후 복원을 할필요 없는 데이터인 경우에는 Hash 함수를 사용
    • DB에 저장된 비밀번호

AOP를 이요한 비밀번호 암호화

aop-context.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"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

application-context.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"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

<import resource="/jdbc-Context.xml"/>
<import resource="/aop-Context.xml"/>
</beans>

SHA256Util Class

package kr.or.iei.common;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.springframework.stereotype.Component;
@Component
public class SHA256Util {

	public String encryptionData(String data, String salt) throws Exception {
		
		MessageDigest mDigest =  MessageDigest.getInstance("SHA-256");
		
		String str=data+salt;
		
		mDigest.update(str.getBytes());
		
		byte[] encryptMsg = mDigest.digest();	// 암호화 처리한 값 리턴
		 
		StringBuffer hexString=new StringBuffer();
		
		for(byte b : encryptMsg) {
			hexString.append(String.format("%02X",b));
		}
		
		return hexString.toString();
	}
}

MemberAOP Class

@Aspect
@Component
public class MemberAOP {

	@Autowired
	private SHA256Util enc;

	// 회원가입 암호화 처리 AOP 로직
	@Pointcut("execution(int kr.or.iei.member.model.service.MemberServiceImpl.insertMember(..))")
	public void insertMemberPointCut() {
	}

	@Before("insertMemberPointCut()")
	public void insertMemberPasswordEncryption(JoinPoint jp) throws Exception {

		Member m = (Member) jp.getArgs()[0];

		String userPwd = m.getUserPwd();
		String userId = m.getUserId();

		String encryptPwd = enc.encryptionData(userPwd, userId);

		m.setUserPwd(encryptPwd);

	}

MemberController Class

@Controller
public class MemberController {

	@Autowired
	private MemberService mService;

	@RequestMapping(value = "/member/memberJoin.do", method = RequestMethod.POST)
	public ModelAndView memberJoinus(Member m, ModelAndView mav) {

		// view페이지 보낸 데이터 받는 방법
		// 1. request 객체 사용 - request.getParameter();
		// 2. @requestParam 사용 - ex) @requestParam String userId
		// 3. VO를 활용하는 방법(서로 다른 여러 객체 사용 가능) - ex) 인자 값을 Member m 설정

		int result = mService.insertMember(m);

		if (result > 0) {
			mav.addObject("msg", "회원 가입 성공");
			mav.addObject("location", "/");
		} else {
			mav.addObject("msg", "회원 가입 실패 - 지속적인 문제 발생시 관리자에게 문의 -");
			mav.addObject("location", "/member/joinPage.do");
		}

		mav.setViewName("member/msg");

		return mav;

	}

MemberService Interface

public interface MemberService {
	int insertMember(Member m);
}

MemberServiceImpl Class

@Service
public class MemberServiceImpl implements MemberService{

	@Override
	public int insertMember(Member m) {
		return mDAO.insertMember(m);
		
	}
}

MemberDAO Class

@Repository
public class MemberDAO {

	@Autowired
	@Qualifier(value = "jdbcTemplate")
	JdbcTemplate jdbc;

	public int insertMember(Member m) {
		
		String query="INSERT INTO MEMBER VALUES(MEMBER_SEQ.NEXTVAL, ?, ?, ?, ?, ?, SYSDATE, 'N')";
		
		return jdbc.update(query, m.getUserId(), m.getUserPwd(), m.getUserName(), m.getAge(), m.getAddress());
		
	}
}
profile
개발자로 매일 한 걸음

0개의 댓글