자바 기반 대칭 키 암호화 알고리즘 분석 및 구현

대칭 키 암호화의 개념과 주요 알고리즘

암호화 기법 중 대칭 키 방식은 동일한 키를 사용해 데이터를 암호화하고 복호화하는 방법이다. 이 방식은 속도가 빠르고 실시간 통신에 적합하지만, 키 관리의 보안성이 핵심 과제가 된다. 아래에서는 자바 환경에서 구현 가능한 주요 대칭 암호화 알고리즘인 DES, 3DES, AES, PBE를 각각 살펴보고, 코드 예제를 통해 동작 원리를 설명한다.

1. DES (Data Encryption Standard)

DES는 56비트 키를 사용하는 고전적인 블록 암호화 알고리즘이다. 현재는 보안상 취약하여 실무 적용이 제한적이지만, 학습 목적이나 레거시 시스템에서 여전히 참고된다. Java Cryptography Architecture(JCA)를 활용하면 간단히 구현할 수 있다.

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.SecretKeyFactory;
import java.security.Key;

public class DesEncryption {
    private static final String PLAIN_TEXT = "Hello Symmetric World";

    public static void main(String[] args) {
        try {
            // 1. 키 생성
            KeyGenerator generator = KeyGenerator.getInstance("DES");
            generator.init(56);
            SecretKey rawKey = generator.generateKey();
            byte[] keyBytes = rawKey.getEncoded();

            // 2. 키 변환
            DESKeySpec spec = new DESKeySpec(keyBytes);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
            Key secretKey = factory.generateSecret(spec);

            // 3. 암복호화 처리
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encrypted = cipher.doFinal(PLAIN_TEXT.getBytes());

            System.out.println("DES Encrypted: " + java.util.Base64.getEncoder().encodeToString(encrypted));

            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decrypted = cipher.doFinal(encrypted);
            System.out.println("DES Decrypted: " + new String(decrypted));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2. Triple DES (3DES)

DES의 보안 한계를 극복하기 위해 설계된 3중 DES는 같은 키 또는 세 개의 서로 다른 키를 사용해 DES를 세 번 적용한다. 키 길이는 112비트 또는 168비트로 증가시켜 보안성을 향상시켰다. 다만 성능이 낮아 점차 폐기되고 있는 추세이다.

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.SecureRandom;

public class TripleDesEncryption {
    private static final String DATA = "Secure Message";

    public static void main(String[] args) {
        try {
            KeyGenerator gen = KeyGenerator.getInstance("DESede");
            gen.init(new SecureRandom()); // 기본 키 길이: 168비트
            SecretKey key = gen.generateKey();

            Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encrypted = cipher.doFinal(DATA.getBytes());

            System.out.println("3DES Encrypted: " + java.util.Base64.getEncoder().encodeToString(encrypted));

            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decrypted = cipher.doFinal(encrypted);
            System.out.println("3DES Decrypted: " + new String(decrypted));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. AES (Advanced Encryption Standard)

AES는 현재 가장 널리 사용되는 대칭 암호 알고리즘으로, 128, 192, 256비트 키를 지원하며 높은 보안성과 효율성을 제공한다. 특히 AES-256은 군사 및 금융 분야에서도 채택되고 있다.

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

public class AesEncryption {
    private static final String MESSAGE = "Top Secret Data";

    public static void main(String[] args) {
        try {
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
            keyGen.init(128, new SecureRandom());
            SecretKey tempKey = keyGen.generateKey();

            // 키 재생성 (직접 사용 가능)
            SecretKey aesKey = new SecretKeySpec(tempKey.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, aesKey);
            byte[] encrypted = cipher.doFinal(MESSAGE.getBytes());

            System.out.println("AES Encrypted: " + java.util.Base64.getEncoder().encodeToString(encrypted));

            cipher.init(Cipher.DECRYPT_MODE, aesKey);
            byte[] decrypted = cipher.doFinal(encrypted);
            System.out.println("AES Decrypted: " + new String(decrypted));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4. PBE (Password-Based Encryption)

PBE는 사용자 비밀번호로부터 암호화 키를 도출하는 방식으로, Salt와 반복 횟수(iteration count)를 통해 사전 공격을 방어한다. MD5나 SHA 해시 함수와 결합되어 키를 생성하며, DES 등의 알고리즘을 기반으로 한다.

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.SecureRandom;

public class PbeEncryption {
    private static final String TEXT = "Private Content";
    private static final char[] PASSPHRASE = "myStrongPass".toCharArray();

    public static void main(String[] args) {
        try {
            SecureRandom random = new SecureRandom();
            byte[] salt = random.generateSeed(8);
            int iterations = 100;

            PBEKeySpec keySpec = new PBEKeySpec(PASSPHRASE);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            javax.crypto.SecretKey key = factory.generateSecret(keySpec);

            PBEParameterSpec paramSpec = new PBEParameterSpec(salt, iterations);
            Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
            cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
            byte[] encrypted = cipher.doFinal(TEXT.getBytes());

            System.out.println("PBE Encrypted: " + java.util.Base64.getEncoder().encodeToString(encrypted));

            cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
            byte[] decrypted = cipher.doFinal(encrypted);
            System.out.println("PBE Decrypted: " + new String(decrypted));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

각 알고리즘은 보안성과 성능 면에서 차이를 보이며, 실제 서비스에서는 AES 또는 PBE와 같은 현대적 알고리즘을 권장한다. 특히 키 관리 및 Salt, IV(Initialization Vector) 사용은 보안 강화에 필수적이다.

태그: java 암호화 대칭키 DES AES

6월 1일 21:03에 게시됨