http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/

 

Java Cipher - 알고리즘, 운용 모드, 패딩의 이해

자바에서는 대칭키 알고리즘을 사용하여 데이터를 암호화/복호화할 때 javax.crypto.Cipher 클래스를 사용한다. 이 클래스의 인스턴스는 정적 메서드인 Cipher.getInstance()를 호출하여 가져올 수 있는데,

happinessoncode.com

 

암호화를 배운적이 없다보니, 상당히 난해하다. 설명은 못하겠고, 참고한 소스는 위의 링크에 있으며, 설명이 잘되있다.

 

1. 암호화 후 복호화 불가능한 암호화가 있고, 복호화 가능한 암호화가 있다.

2. 복호화하여 쓸 필요가 있어 복호화가 가능한 라이브러리를 찾아보니 AES256이 있다.

 

누가 만들어놓은 것을 가져온거라서 자세한 내용은 잘 모른다.

 

volatile 이라는 키워드라던가, synchronized 라던가 암호화 라이브러리에서 특히 많이 보이는 것 같던데 관련 부분을 읽어봐도 잘 이해는 안된다.

 

큰 과정은 이렇고, 비밀키가 노출이 되면 안된다.

1. 암호화 : 평문 + 비밀키 -> 암호문

2. 복호화 : 암호문 + 비밀키 -> 평문

 

 

 

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

import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;

@Component
public class AES256Crypto {
	
	/*32 bit key : 32 �ڸ�*/
	final static String secretKey = "123kjasaldkvnasdlfqwerdfadsfasda";
	
	/*volatile : �޸𸮿� ������ �ε�*/
	private static volatile AES256Crypto INSTANCE;
	
	/*IV option : 16bit*/
	static String IV = "";
	
	/* ��ü �ν��Ͻ� �������� */
	public static AES256Crypto getInstance() {
		if(INSTANCE == null) {
			synchronized (AES256Crypto.class) {
				if(INSTANCE == null) {
					INSTANCE = new AES256Crypto();
				}
			}
		}
		return INSTANCE;
	}
	
	private AES256Crypto() {
        IV = secretKey.substring(0, 16);
    }
	
	public String encryptAES256(String plainText) 
			throws NoSuchAlgorithmException, 
			NoSuchPaddingException, 
			InvalidKeyException, 
			InvalidAlgorithmParameterException, 
			IllegalBlockSizeException, 
			BadPaddingException,
			UnsupportedEncodingException {
		byte[] key = secretKey.getBytes();
		SecretKey secretKey = new SecretKeySpec(key, "AES");
		
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(IV.getBytes()));
		
		byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
        String enStr = new String(Base64.encodeBase64(encrypted));
        
		return enStr;
	}
	
	public String decryptAES256(String encryptedText) 
			throws NoSuchAlgorithmException, 
			NoSuchPaddingException, 
			UnsupportedEncodingException, 
			IllegalBlockSizeException, 
			BadPaddingException, 
			InvalidKeyException, 
			InvalidAlgorithmParameterException {
		
		byte[] keyData = secretKey.getBytes();
        SecretKey secureKey = new SecretKeySpec(keyData, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secureKey, new IvParameterSpec(IV.getBytes("UTF-8")));
        byte[] byteStr = Base64.decodeBase64(encryptedText.getBytes());
        return new String(cipher.doFinal(byteStr), "UTF-8");
	}
}