Java

암호화, AES-256-CBC를 이용해서 암호화/복호화 하는 방법

greenyellow-s 2025. 3. 24. 15:57
728x90
반응형

AES-256-CBC

양방향/대칭 키 암호화 방식

  • 암호화 및 복호화에 사용되는 키 값이 동일
  • 데이터를 256비트 키와 CBC 모드(Cipher Block Chaining)로 암호화
  • AES는 Advanced Encryption Standard 의 약자로, AES-256은 256 비트 키를 사용하는 AES 알고리즘
  • 고속의 대칭키 블록 암호화 알고리즘

CBC

가장 일반적으로 사용되는 작동 모드

 

블록을 그대로 암호화하지 않고 이전에 암호화했던 블록과 XOR 연산을 수행하는데,

첫 번째 블록은 이전에 암호화한 블럭이 없기 때문에 IV를 이용

 


동작 원리

1. 초기화 벡터(IV, Initialization Vector)

  • CBC 모드는 IV라는 추가적인 값을 필요로 한다.
  • 암호화 과정의 첫 번째 블록에만 사용되고, 그 후에는 암호화된 이전 블록의 결과가 다음 블록에 영향을 미친다.
  • 암호화된 결과와 함께 저장되거나 전송되며, 복호화 시 동일한 IV를 사용해야한다.

 

2. 블록 암호화

  • 데이터 블록 크기로 나눠져 암호화
  • 각 블록은 암호화 키와 IV를 사용하여 암호화
  • 이전 암호화된 블로고가 현재 블록을 XOR 연산 후 암호화

암호화 및 복호화 과정

1. 암호화

  • 원본 데이터를 128비트 크기의 블록으로 분할
  • IV와 대칭 키를 사용하여 첫 번째 블록을 암호화
  • 첫 번째 암호문 블록은 두 번째 브록을 암호화할 떼 XOR 연산을 통해 사용
  • 이 과정을 모든 블록에 대해 반복하여 데이터를 암호화

 

2. 복호화

  • 암호화된 데이터를 블록 단위로 복호화
  • 각 암호문 블록을 복호화할 때, 이전 암호문 블록과 XOR 연산을 통해 원본 데이터가 복원
  • IV와 데칭 키를 사용하여 암호문을 복호화

예시 - java

 

조건

  • 평문을 입력받고 암호화 / 암호화된 문자열 받아 복호화
  • AES-256-CBC 사용해서 암호화/복호화
  • 스티링 변환은 모두 HEX 형태로 사용

import javax.crypto.Chipher (크립토 사이퍼) 클래스 사용

 

 

암호화 로직

  1. IV 생성
  2. 암호화 객체 생성 - AES 256 CBC
  3. 평문 암호화
  4. IV + 평문 결합

 

1. IV 생성

byte[] ivBytes = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(ivBytes);  // 랜덤 IV 생성
IvParameterSpec iv = new IvParameterSpec(ivBytes);  // IV 설정
String ivText = HexFormat.of().formatHex(iv.getIV()); // IV를 16진수 문자열로 변환

 

2. 암호화 객체 생성 - AES 256 CBC

// 암호화 객체 생성
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, this.secretKey, iv); // 암호화 준비

 

 

3. 평문 암호화

// 평문 암호화
byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8); // 바이트 배열로 변환
byte[] cipherBytes = cipher.doFinal(plainBytes); // 암호화 실행
String cipherText = HexFormat.of().formatHex(cipherBytes); // Hex로 변환

 

4. IV + 평문 결합

ivText + cipherText

 

복호화 로직

  1. 암호화 문자에서 IV 추출
  2. 암호화 객체 생성
  3. IV 제외한 문자를 복호화

 

1. 암호화 문자에서 IV 추출

String ivText = encryptedText.substring(0, 32); // 처음 32문자(16바이트)를 잘라서 문자열 추출
byte[] ivBytes = HexFormat.of().parseHex(ivText); // byte[] 배열로 변환
IvParameterSpec iv = new IvParameterSpec(ivBytes); // 초기화 백터를 담는 객체 = ivBytes 배열을 사용하여 IV 객체를 생성

 

16바이트 길이의 값이 Hex 형식으로 저장되어있기 때문에 32개의 문자로 표현

(* AES의 블록 크기가 128비트, 즉 16바이트이기 때문)

 

2. 암호화 객체 생성

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // cipher 객체 생성
cipher.init(Cipher.DECRYPT_MODE, this.secretKey, iv); // 복호화 모드로 초기화

 

3. IV 제외한 문자를 복호화

byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8); // 평문을 바이트 배열로 변환
byte[] cipherBytes = cipher.doFinal(plainBytes); // 복호화
String cipherText = HexFormat.of().formatHex(cipherBytes); // 복호화된 바이트 배열을 16진수 문자열로 변환

 

문자열을 UTF-8 인코딩을 사용하여 바이트 배여로 변환한다.

 

 

암호화 복호화
cipher.init(Cipher.ENCRYPT_MODE, this.secretKey, iv); cipher.init(Cipher.DECRYPT_MODE, this.secretKey, iv);

 

728x90
반응형