본문 바로가기
Project/소경관

[소경관] : SHA-256 암호화 알고리즘, AES128-CBC암,복호화 알고리즘 적용

by 오주현 2021. 12. 20.
반응형
SHA-256 암호화 알고리즘, AES128-CBC암,복호화 알고리즘 적용

내용


  • 회원 가입 시 개인을 식별할 수 있는 정보에 대해 암호화 해야 한다.
    • 정보통신망법, 개인정보보호법
    • 식별 정보
      • 이메일
      • 전화번호
      • 주민등록번호
      • 계좌정보
  • 암, 복호화 키가 같으면 대칭키, 다르면 비대칭키
    • 비대칭키
      • 보안 강도가 쌔다.
      • 속도가 느리다.
      • 공인인증서, 지문, 공동인증서 등에 사용된다.
  • 비밀번호는 복호화되지 않는 단방향 암호화를 사용하여 비밀번호를 저장한다.
  • 암호화는 단방향과 양방향이 있다.
    • 단방향
      • 암호화만 지원한다.
      • 해시 암호화
        • 절대 복호화 하지 않기 위해 사용한다.
        • 속도가 빠르고 암호화 되는 값의 크기가 일정하다.
        • 완전한지에 대한 검사가 오래 걸리기 때문에 해시 암호화를 사용한다.
        • SHA-256 암호화 알고리즘을 사용한다.
    • 양방향
      • 이메일, 전화번호, 주민등록번호, 계좌정보는 대칭키 암호화 기술을 적용한다.
        • AES 128 - CBC 암호화 알고리즘을 사용한다.
          • 현존 대칭키 중 가장 강력하다.

코드 & 설명


<!-- 데이터 전송시 문자가 깨지는 현상을 방지하기 위한 BASE64 인코딩 사용할 라이브러리 추가 -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.10</version>
		</dependency>

BASE64 인코딩 라이브러리를 다운한다.

  • 암,복호화 수행시, 특수문자, 한자, 한글 등 특수한 문자들에 아스키 코드로 인식이 가능하도록 인코딩할 때, 일괄 변환하는 방법이다.
  • Maven을 활용하여 Pom.xml에 코드를 추가하여 다운로드를 진행한다.

package poly.util;

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

public class EncryptUtil {

	/*
	 * 암호화 알고리즘에 추가시킬 암호화 문구
	 * 
	 * 일반적인 암호화 알고리즘 SHA-256을 통해서만 암호화 시킬 경우, 암호화 된 값만 보고 일반적인 비밀번호에 대한 값을 쉽게 예측이
	 * 가능함 따라서, 암호화 할 때 암호화되는 값에 추가적인 문자열을 붙여서 함께 암호화를 진행한다.
	 */
	final static String addMessage = "ohjuhyeon";

	/*
	 * AES128-CBC 암호화 알고리즘에 사용되는 초기 백터와 암호화 키
	 */

	/*
	 * 해시 알고리즘 ( 단방향 암호화 알고리즘 ) SHA-256
	 * 
	 * @param 암호화 시킬 값
	 * 
	 * @return 암호화된 값
	 */
	public static String encHashSHA256(String str) throws Exception {

		String res = ""; // 암호화 결과값이 저장되는 변수
		String plantText = addMessage + str; // 암호화 시킬 값에 보안 강화를 위해 임의 값을 추가한다.

		try {
			/*
			 * Java는 기본적으로 표준 암호화 알고리즘을 java.security 패키지를 통해 제공한다. 여러 해시 알고리즘 중 가장 많이 사용되는
			 * SHA-256을 지원하고 있다.
			 */
			MessageDigest sh = MessageDigest.getInstance("SHA-256");

			sh.update(plantText.getBytes());

			byte byteData[] = sh.digest();

			StringBuffer sb = new StringBuffer();

			for (int i = 0; i < byteData.length; i++) {
				sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
			}

			res = sb.toString();

			// Java에서 제공하는 알고리즘이 아닌 경우, 에러 발생
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();

			res = "";

		}

		return res;

	}
}
  • SHA-256 해시 암호화 알고리즘 적용

package poly.util;

public class EncryptTest {
	
	public static void main(String[] args) throws Exception {
		
		System.out.println("------------------------------");
		System.out.println("해시 암호화 알고리즘 테스트");
		
		//암호화 문자열
		String str = "암호화할 문자열";
		
		//복호화가 불가능한 해시 암호화 알고리즘 실행
		String hashEnc = EncryptUtil.encHashSHA256(str);
		
		//해시 암호화 알고리즘 결과 출력
		System.out.println("hashEnc : " + hashEnc);
		
		System.out.println("------------------------------");
		
	}

}

package poly.util;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.tomcat.util.codec.binary.Base64;

public class EncryptUtil {

	/*
	 * 암호화 알고리즘에 추가시킬 암호화 문구
	 * 
	 * 일반적인 암호화 알고리즘 SHA-256을 통해서만 암호화 시킬 경우, 암호화 된 값만 보고 일반적인 비밀번호에 대한 값을 쉽게 예측이
	 * 가능함 따라서, 암호화 할 때 암호화되는 값에 추가적인 문자열을 붙여서 함께 암호화를 진행한다.
	 */
	final static String addMessage = "ohjuhyeon";

	/*
	 *--------------------------------------------------------------------------------------------
	 * AES128-CBC 암호화 알고리즘에 사용되는 초기 백터와 암호화 키
	 */
	
	// 초기 백터 (16Byte 크기를 가지며, 16Byte 단위로 암호화 시, 암호화 할 총 길이가 16Byte가 되지 못 하면 뒤에 추가하는 바이트)
	final static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
	
	//AES128-CBC 암호화 알고리즘에 사용되는 키 (16자리 문자만 가능하다.)
	final static String key = "Ohjuhyeon1234567"; // 16글자가 필요하다. (영문 1글자당 1Byte)
	//--------------------------------------------------------------------------------------------
	
	/*
	 * 해시 알고리즘 ( 단방향 암호화 알고리즘 ) SHA-256
	 * 
	 * @param 암호화 시킬 값
	 * 
	 * @return 암호화된 값
	 */
	public static String encHashSHA256(String str) throws Exception {

		String res = ""; // 암호화 결과값이 저장되는 변수
		String plantText = addMessage + str; // 암호화 시킬 값에 보안 강화를 위해 임의 값을 추가한다.

		try {
			/*
			 * Java는 기본적으로 표준 암호화 알고리즘을 java.security 패키지를 통해 제공한다. 여러 해시 알고리즘 중 가장 많이 사용되는
			 * SHA-256을 지원하고 있다.
			 */
			MessageDigest sh = MessageDigest.getInstance("SHA-256");

			sh.update(plantText.getBytes());

			byte byteData[] = sh.digest();

			StringBuffer sb = new StringBuffer();

			for (int i = 0; i < byteData.length; i++) {
				sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
			}

			res = sb.toString();

			// Java에서 제공하는 알고리즘이 아닌 경우, 에러 발생
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();

			res = "";

		}

		return res;
	}
	
	//--------------------------------------------------------------------------------------------
	/*
	 * AES128 CBC 암호화 함수
	 *  128은 암호화 키 길이를 의미한다. 
	 *  128bit = 16byte (1Byte=8bit * 16 = 128)
	 */
	public static String encAES128CBC(String str)
		throws UnsupportedEncodingException, NoSuchAlgorithmException,NoSuchPaddingException,
		InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
		
		byte[] textBytes = str.getBytes("UTF-8");
		AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
		SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
		Cipher cipher = null;
		cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
		return Base64.encodeBase64String(cipher.doFinal(textBytes));
	}
	
	/*
	 * AES128 CBC 복호화 함수
	 *  128은 암호화 키 길이를 의미한다. 
	 *  128bit = 16byte (1Byte=8bit * 16 = 128)
	 */
	public static String decAES128CBC(String str)
		throws UnsupportedEncodingException, NoSuchAlgorithmException,NoSuchPaddingException,
		InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
	
		byte[] textBytes = Base64.decodeBase64(str);
		AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
		SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
		return new String(cipher.doFinal(textBytes), "UTF-8");

	}
			 
}
  • AES128-CBC 암호화 알고리즘 추가 적용
  • AES128-CBC 복호화 알고리즘 추가 적용
  • 최종 코드

package poly.util;

public class EncryptTest {
	
	public static void main(String[] args) throws Exception {
		
		System.out.println("------------------------------");
		System.out.println("해시 암호화 알고리즘 테스트");
		
		//암호화 문자열
		String str = "암호화할 문자열";
		
		//복호화가 불가능한 해시 암호화 알고리즘 실행
		String hashEnc = EncryptUtil.encHashSHA256(str);
		
		//해시 암호화 알고리즘 결과 출력
		System.out.println("hashEnc : " + hashEnc);
		
		System.out.println("------------------------------");
		
		System.out.println("AES128-CBC 암, 복호화 알고리즘");
		
		//AES128-CBC 암호화 알고리즘 실행
		String enc = EncryptUtil.encAES128CBC(str);
		
		//AES128-CBC 암호화 알고리즘 결과 출력
		System.out.println("enc : " + enc);
		
		//AES128-CBC 복호화 알고리즘 실행
		String dec = EncryptUtil.decAES128CBC(enc);
		
		//AES128-CBC 복호화 알고리즘 결과 출력
		System.out.println("dec : " + dec);
		
		System.out.println("------------------------------");
	}

}
  • AES128-CBC 암호화 알고리즘 추가 적용 테스트 완료
  • AES128-CBC 복호화 알고리즘 추가 적용 테스트 완료
  • 최종 코드

참고


  • 21.12.18 | 해시 암호화 알고리즘 파트 생성
    • 알고리즘 테스트 파일 생성 필요
    • AES128-CBC 암호화 함수 생성 필요
    • AES128-CBC 암호화 함수 테스트 생성 필요
  • 21.12.20 | 해시 암호화 알고리즘 테스트 성공
  • 21.12.20 | AES128-CBC 암호화 알고리즘 추가 적용 완료
  • 21.12.20 | AES128-CBC 복호화 알고리즘 추가 적용 완료
  • 21.12.20 | AES128-CBC 암호화 알고리즘 추가 적용 테스트 완료
  • 21.12.20 | AES128-CBC 복호화 알고리즘 추가 적용 테스트 완료
반응형

댓글