목차
- 자바 소스 코드 컴파일 명령 javac 예제 이전 포스팅
- 자바 random 활용 AES 암호화 랜덤 키 생성 예제 이전 포스팅
- 자바 AES 256 ECB 암복호화 예제 이전 포스팅
- C언어에서 Openssl 라이브러리 활용한 AES 256 CBC 암복호화 예제 이전포스팅
- 자바 AES 256 랜덤 키, IV 문자열 생성 예제
- 자바 AES 256 CBC 문자열 암호화 예제
- 자바 AES 256 CBC 암호문 복호화 예제
자바 소스 코드 컴파일 명령 javac 예제 이전 포스팅
오늘 다룰 포스팅은 이전 포스팅에서 다뤘던 AES 256 암복호화의 심화 학습 예제입니다. AES 암호화는 평문을 암호문으로 바꾸는 것이지만 암호화하는 방식이 여러가지 있습니다. 이러한 것들을 체인 혹은 모드라고 합니다. 이전 포스팅에서는 ECB 모드 암복호화 예제를 다뤘습니다.
오늘은 CBC 모드로 암복호화를 하려고합니다. CBC 모드 암복호화에는 Key 뿐만아니라 IV라는 값이 포함됩니다. 즉, 하나의 블록을 암복호화할 때마다 IV값이 XOR되어 값을 추정하기 어렵게 만드는 모드입니다.
오늘 예제를 실행하기 위해 자바 소스 코드를 컴파일하여 실행파일을 얻어야합니다. 아직 javac 명령어로 자바 소스 코드 컴파일 방법을 모르신다면 아래 링크의 포스팅을 참고하여 학습해주세요.
2023.08.10 - [Linux] - [Linux/Java] 리눅스 우분투에서 java 컴파일 및 실행 예제(javac)
자바 random 활용 AES 암호화 랜덤 키 생성 예제 이전 포스팅
오늘도 이전 포스팅과 마찬가지로 AES 암복호화에 랜덤한 문자열을 사용할 예정입니다. 또한 추가된 IV도 16바이트 크기가 필요합니다. 이 값도 random 메소드를 사용하여 랜덤생성할 예정입니다.
아직 SecureRandom 클래스의 random 메소드 사용법을 잘 모르신다면 아래 링크를 참고하여 학습해주세요.
2023.08.17 - [Java] - [Java/Linux] 자바 랜덤 메소드 활용 사용자 비밀번호 생성 예제(SecureRandom)
자바 AES 256 ECB 암복호화 예제 이전 포스팅
만약 AES 256 ECB 모드 암복호화 예제를 아직 따라하지 않으셨다면 제일 기초가되는 ECB 암복호화 예제를 우선 학습해주세요. CBC는 암복호화 모드가 다르기때문에 제일 기본이되는 ECB의 암복호화 방법을 익히는것이 중요합니다. 아래 링크를 참고해주세요.
2023.08.17 - [Java] - [Java/Linux] 자바 AES 256 ECB 모드 대칭 암호화 및 복호화 예제
C언어에서 Openssl 라이브러리 활용한 AES 256 CBC 암복호화 예제 이전포스팅
오늘 포스팅에서 다루는 것은 자바 언어에서 AES 256 CBC 암복호화하는 것입니다. C 혹은 C++ 환경에서 CBC 모드 암복호화하는 예제도 이전 포스팅에서 다뤘습니다. 만약 이 부분이 궁금하시다면 아래 링크를 참고해주세요.
2023.07.31 - [C] - [C/C++] Openssl 활용 AES256 암호화 및 복호화 예제 - 3(CBC, CTR, 등)
자바 AES 256 랜덤 키, IV 문자열 생성 예제
아래는 AES 256 CBC 모드 암복호화에 사용할 32바이트 크기의 랜덤 키와 16바이트 크기의 IV 를 생성하는 예제입니다.
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Example {
private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
private static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String SPECIALCHARS = "!@#$%^&*()-_=+[]{}|;:,.<>?";
private static final String AES_ALGORITHM = "AES";
private static final String AES_MODE = "AES/ECB/PKCS5Padding";
public static String generateRandomPassword() {
SecureRandom random = new SecureRandom();
List<String> characters = new ArrayList<>();
characters.add(LOWERCASE);
characters.add(UPPERCASE);
characters.add(SPECIALCHARS);
StringBuilder passwordBuilder = new StringBuilder();
while (passwordBuilder.length() < 32) {
String randomCharacterList = characters.get(random.nextInt(characters.size()));
int randomIndex = random.nextInt(randomCharacterList.length());
char randomChar = randomCharacterList.charAt(randomIndex);
passwordBuilder.append(randomChar);
}
return passwordBuilder.toString();
}
public static void main(String[] args) throws Exception {
String plainText = "Hello, AES in CBC mode!";
String key = generateRandomPassword();
String iv = generateRandomPassword().substring(16);
System.out.println("Plain Text: " + plainText);
System.out.println("Key: " + key);
System.out.println("Iv: " + iv);
}
}
자바 AES 256 CBC 문자열 암호화 예제
아래는 AES 256 CBC 모드로 평문의 문자열을 암호화하는 예제입니다.
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
public class Example {
private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
private static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String SPECIALCHARS = "!@#$%^&*()-_=+[]{}|;:,.<>?";
private static final String AES_ALGORITHM = "AES";
private static final String AES_MODE = "AES/CBC/PKCS5Padding";
public static String generateRandomPassword() {
SecureRandom random = new SecureRandom();
List<String> characters = new ArrayList<>();
characters.add(LOWERCASE);
characters.add(UPPERCASE);
characters.add(SPECIALCHARS);
StringBuilder passwordBuilder = new StringBuilder();
while (passwordBuilder.length() < 32) {
String randomCharacterList = characters.get(random.nextInt(characters.size()));
int randomIndex = random.nextInt(randomCharacterList.length());
char randomChar = randomCharacterList.charAt(randomIndex);
passwordBuilder.append(randomChar);
}
return passwordBuilder.toString();
}
public static void main(String[] args) throws Exception {
String plainText = "Hello, AES in CBC mode!";
String key = generateRandomPassword();
String iv = generateRandomPassword().substring(16);
System.out.println("Plain Text: " + plainText);
System.out.println("Key: " + key);
System.out.println("Iv: " + iv);
// Encrypt
String encryptedText = encryptAESECB(plainText, key, iv);
System.out.println("Encrypted Text: " + encryptedText);
}
public static String encryptAESECB(String plainText, String key, String iv) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), AES_ALGORITHM);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance(AES_MODE);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
}
자바 AES 256 CBC 암호문 복호화 예제
아래는 AES 256 CBC 모드로 암호문을 복호화하는 예제입니다.
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
public class Example {
private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
private static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String SPECIALCHARS = "!@#$%^&*()-_=+[]{}|;:,.<>?";
private static final String AES_ALGORITHM = "AES";
private static final String AES_MODE = "AES/CBC/PKCS5Padding";
public static String generateRandomPassword() {
SecureRandom random = new SecureRandom();
List<String> characters = new ArrayList<>();
characters.add(LOWERCASE);
characters.add(UPPERCASE);
characters.add(SPECIALCHARS);
StringBuilder passwordBuilder = new StringBuilder();
while (passwordBuilder.length() < 32) {
String randomCharacterList = characters.get(random.nextInt(characters.size()));
int randomIndex = random.nextInt(randomCharacterList.length());
char randomChar = randomCharacterList.charAt(randomIndex);
passwordBuilder.append(randomChar);
}
return passwordBuilder.toString();
}
public static void main(String[] args) throws Exception {
String plainText = "Hello, AES in CBC mode!";
String key = generateRandomPassword();
String iv = generateRandomPassword().substring(16);
System.out.println("Plain Text: " + plainText);
System.out.println("Key: " + key);
// Encrypt
String encryptedText = encryptAESCBC(plainText, key, iv);
System.out.println("Encrypted Text: " + encryptedText);
// Decrypt
String decryptedText = decryptAESCBC(encryptedText, key, iv);
System.out.println("Decrypted Text: " + decryptedText);
}
public static String encryptAESCBC(String plainText, String key, String iv) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), AES_ALGORITHM);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance(AES_MODE);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decryptAESCBC(String encryptedText, String key, String iv) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), AES_ALGORITHM);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance(AES_MODE);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes);
}
}