반응형

📝AES

대칭키 알고리즘으로 "대칭키" 하나로 암호화 및 복호화 모두 진행하고 문자열 길이에 제약이 없다.

 

📝AES 암호화 키 방식

  • AES128
    • 암호화 키를 128bit 즉 16byte로 설정한다.
  • AES192
    • 암호화 키를 192bit 즉 24byte로 설정한다.
  • AES256
    • 암호화 키를 256bit 즉 32byte로 설정한다.

 

📝Secret Key

Secret Key는 평문을 암호화하는데 사용되며 절대로 외부에 노출되어서는 안됩니다. AES128, AES192, AES256에 해당하는 암호화키입니다.

 

📝AES 암호화 방식

  • ECB
    • 평문을 일정 크기의 블록으로 잘라 각 블록을 암호화시키는데 암호화와 복호화에 사용되는 키가 동일하기 때문에 유추가능할 경우 보안에 취약하다
    • 예) ABC를 암호화 시켜서 123이 나오면 DABC를 했을땐 4123으로 유추가 가능

 

 

  • CBC
    • ECB의 보안 취약을 보완한 방식으로 보안성이 제일 높은 암호화 방법으로 가장 많이 사용한다
    • IV라는 추가적인 키를 사용하며 IV키로 1차 암호화 후 2차로  Secret Key로 암호화하는 방식이다. 일반적으로 IV키는 고정적으로 하지 않으며 랜덤한 값으로 하는게 좋다

 

 

📝PKCS5 Padding

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

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.commons.lang.RandomStringUtils;

public class Test {
	

	/** ───── IV키 생성 설정 ───── **/
	private final static int BYTE_LENGTH = 16;
	private final static boolean USE_LETTERS = true;
	private final static boolean USE_NUMBERS = false;
	
	/** ───── 암호화키 바이트 종류 ───── **/
	private final static String SECRET_KEY_128 = "aeskey1234567898";                 // 16byte == 128bit
	private final static String SECRET_KEY_192 = "aeskey12345678987654321a";         // 24byte == 192bit
	private final static String SECRET_KEY_256 = "aeskey12345678987654321asekey987"; // 32byte == 256bit
	
	
	private final static String SECRET_KEY = SECRET_KEY_256; // 32byte == 256bit
	private final static String IV = RandomStringUtils.random(BYTE_LENGTH, USE_LETTERS, USE_NUMBERS); // 랜덤 IV값
	private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; // AES 암호화 알고리즘의 CBC 방식을 채용하고 비는 바이트는 PKCS5Padding 방식을 채용

	
	public static void main(String[] args) throws java.io.IOException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
	 
		String password = "암호화 해주세요~";
		String encryptedPassword = encrypt(password);
		String decryptedPassword = decrypt(encryptedPassword);
			
		System.out.println("password : " +  password);
		System.out.println("encryptedPassword : " +  encryptedPassword);
		System.out.println("decryptedPassword : " +  decryptedPassword);
	
	}


	/** ───── 암호화 ───── **/
	public static String encrypt(String passwordToEncrypt) throws NoSuchPaddingException, NoSuchAlgorithmException,
         InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

		Cipher cipher = Cipher.getInstance(TRANSFORMATION);
		SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
		IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));

		cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

		return Base64.getEncoder().encodeToString(cipher.doFinal(passwordToEncrypt.getBytes(StandardCharsets.UTF_8)));
   }

	/** ───── 복호화 ───── **/
	public static String decrypt(String passwordToDecrypt) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
         InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
	   
	   Cipher cipher = Cipher.getInstance(TRANSFORMATION);
	   SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
	   IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));

	   cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

	   return new String(cipher.doFinal(Base64.getDecoder().decode(passwordToDecrypt)), "UTF-8");
   }
}

암호화하려는 데이터가 블록사이즈를 채우지 못한 경우 부족한 길이만큼 패딩을 하는 방식이다 예) A로 끝나고 8바이트의 블록사이즈라면 7바이트를 공백으로 채우는 방식

 

 

🔗 참고 및 출처

https://veneas.tistory.com/entry/JAVA-%EC%9E%90%EB%B0%94-AES-%EC%95%94%ED%98%B8%ED%99%94-%ED%95%98%EA%B8%B0-AES-128-AES-192-AES-256
https://velog.io/@reedfoxy/CBC-%EB%B8%94%EB%A1%9D-%EC%95%94%ED%98%B8%ED%99%94IV-Initialization-Vector-%EC%82%AC%EC%9A%A9-%EC%A0%84%EB%9E%B5

반응형