Files
java-examples/docs/security/cipher.md
2025-03-12 10:43:35 +09:00

14 KiB

자바에서 AES와 RSA 암호화 알고리즘을 사용할 때 지원되는 운용 모드, 패딩, 키 길이, 그리고 필요한 매개변수를 표로 정리하겠습니다. JCA/JCE에서 제공하는 기본 설정을 기준으로 하며, JDK 버전(예: JDK 8, 11, 17 등) 및 사용 중인 제공자(Provider, 예: SunJCE, Bouncy Castle)에 따라 일부 차이가 있을 수 있습니다.


AES (Advanced Encryption Standard)

항목 설명
운용 모드 - ECB (Electronic Codebook): 블록 단위로 독립적 암호화 (보안성 낮음, 권장되지 않음).
- CBC (Cipher Block Chaining): 이전 블록과 XOR 연산, IV 필요.
- CTR (Counter): 스트림 암호처럼 동작, IV 또는 논스 필요.
- GCM (Galois/Counter Mode): 인증 암호화, IV 및 추가 인증 데이터(AAD) 지원.
- CFB (Cipher Feedback): 스트림 암호화, IV 필요.
- OFB (Output Feedback): 스트림 암호화, IV 필요.
패딩 - PKCS5Padding (또는 PKCS7Padding): 블록 크기에 맞게 패딩 추가 (기본값).
- NoPadding: 패딩 없음, 데이터 길이가 블록 크기의 배수여야 함.
- ISO10126Padding: 랜덤 패딩 (일부 제공자에서 지원).
키 길이 - 128비트 (기본값).
- 192비트.
- 256비트 (JCE Unlimited Strength Policy 필요 시 설치).
필요한 매개변수 - IV (Initialization Vector): CBC, CTR, GCM, CFB, OFB 모드에서 필요 (일반적으로 16바이트).
- Nonce: CTR, GCM에서 사용 가능.
- AAD (Additional Authenticated Data): GCM 모드에서 인증용 추가 데이터 (선택적).
- Tag 길이: GCM 모드에서 인증 태그 길이 (기본 128비트, 96, 104, 112, 120 등 조정 가능).
Cipher 형식 "AES/[운용모드]/[패딩]" 예: "AES/CBC/PKCS5Padding", "AES/GCM/NoPadding".

참고

  • AES는 블록 크기가 128비트(16바이트)로 고정되어 있습니다.
  • ECB는 보안 취약성이 있어 권장되지 않으며, GCM은 인증과 암호화를 동시에 제공해 현대 애플리케이션에서 선호됩니다.
  • 예제: Cipher.getInstance("AES/GCM/NoPadding").

RSA (Rivest-Shamir-Adleman)

항목 설명
운용 모드 - RSA 자체는 블록 암호화로 동작하며, 별도의 운용 모드 없음.
- 단일 블록 암호화/복호화 또는 서명/검증 용도로 사용.
- 하이브리드 암호화 시 AES와 결합 가능 (RSA로 AES 키 암호화).
패딩 - NoPadding: 패딩 없음 (데이터 길이가 키 크기보다 작아야 함, 권장되지 않음).
- PKCS1Padding: PKCS#1 v1.5 패딩 (암호화/서명에 사용, 기본값).
- OAEPWith<해시>AndMGF1Padding: OAEP 패딩 (예: "OAEPWithSHA-256AndMGF1Padding"), 더 안전.
- OAEPPadding: 기본 OAEP (구형, 권장되지 않음).
키 길이 - 512비트 (취약, 사용 금지).
- 1024비트 (현재 취약, 권장되지 않음).
- 2048비트 (표준).
- 4096비트 (높은 보안 요구 시).
필요한 매개변수 - PublicKey/PrivateKey: 공개키/개인키 쌍.
- OAEP 매개변수: OAEP 사용 시 OAEPParameterSpec로 해시 알고리즘(SHA-256 등)과 MGF1(Mask Generation Function) 지정.
- 서명 시 해시: 예: "SHA256withRSA" (RSA와 결합된 해시 알고리즘).
Cipher 형식 "RSA/[운용모드]/[패딩]" 예: "RSA/None/PKCS1Padding", "RSA/None/OAEPWithSHA-256AndMGF1Padding".

참고

  • RSA는 비대칭 알고리즘이므로 대량 데이터 암호화에는 적합하지 않습니다. 주로 키 교환이나 디지털 서명에 사용됩니다.
  • OAEP 패딩은 PKCS#1 v1.5보다 안전하며, SHA-256 이상의 해시와 함께 사용하는 것이 권장됩니다.
  • 최대 암호화 가능한 데이터 크기는 키 길이와 패딩에 따라 달라집니다 (예: 2048비트 키 + PKCS1Padding = 최대 245바이트).

AES와 RSA 비교 요약

특징 AES RSA
유형 대칭키 암호화 비대칭키 암호화
주요 용도 데이터 암호화 키 교환, 디지털 서명
속도 빠름 느림
키 길이 128, 192, 256비트 1024, 2048, 4096비트
운용 모드 ECB, CBC, GCM 등 다양 없음 (단일 블록 암호화)
패딩 PKCS5Padding, NoPadding 등 PKCS1Padding, OAEP 등

예제 코드

AES 암호화

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class AesExample {
    public static void main(String[] args) throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256);
        SecretKey key = keyGen.generateKey();

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] iv = new byte[16]; // IV는 랜덤으로 생성해야 함
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        byte[] encrypted = cipher.doFinal("Hello, AES!".getBytes());
        System.out.println(new String(encrypted));
    }
}

RSA 암호화

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;

public class RsaExample {
    public static void main(String[] args) throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair keyPair = keyGen.generateKeyPair();

        Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
        byte[] encrypted = cipher.doFinal("Hello, RSA!".getBytes());
        System.out.println(new String(encrypted));
    }
}

추가로 궁금한 점이나 특정 항목에 대한 자세한 설명이 필요하면 말씀해주세요!


AES-GCM (Galois/Counter Mode)은 AES 암호화 알고리즘의 운용 모드 중 하나로, 대칭키 암호화와 인증을 동시에 제공하는 인증 암호화 (Authenticated Encryption, AE) 방식입니다. 이 모드는 현대 보안 애플리케이션에서 널리 사용되며, 특히 TLS/SSL, IPsec, 디스크 암호화 등에서 표준으로 채택되고 있습니다. 아래에서 AES-GCM의 상세한 특징, 동작 방식, 매개변수, 장단점 등을 정리하겠습니다.


AES-GCM의 주요 특징

  1. 대칭키 암호화:

    • AES 블록 암호를 기반으로 하며, 블록 크기는 128비트(16바이트)로 고정됩니다.
    • 키 길이는 128비트, 192비트, 256비트 중 선택 가능.
  2. 인증 제공:

    • 암호화된 데이터의 무결성과 출처 인증을 보장하기 위해 **인증 태그 (Authentication Tag)**를 생성합니다.
    • 별도의 MAC(Message Authentication Code) 계산이 필요 없음.
  3. 스트림 암호처럼 동작:

    • CTR(Counter) 모드를 기반으로 하여, 입력 데이터 길이에 관계없이 암호화 가능 (블록 크기의 배수일 필요 없음).
  4. Galois 필드 연산:

    • 인증 태그 생성에 GF(2^128) (Galois Field) 연산을 사용하며, 이를 통해 효율적이고 안전한 인증을 구현.

AES-GCM의 동작 방식

  1. 입력:

    • 평문 (Plaintext): 암호화할 데이터.
    • 키 (Key): AES 키 (128, 192, 256비트).
    • IV (Initialization Vector) 또는 Nonce: 초기화 벡터 (일반적으로 12바이트 권장).
    • AAD (Additional Authenticated Data): 인증만 필요한 추가 데이터 (선택적, 암호화되지 않음).
  2. 과정:

    • CTR 모드 암호화: IV와 카운터를 결합하여 AES로 키스트림(Key Stream)을 생성하고, 평문과 XOR 연산을 통해 암호문을 생성.
    • 인증 태그 생성: 암호문, AAD, IV 등을 Galois 필드 연산(GMAC)을 통해 인증 태그로 변환.
    • 출력: 암호문(Ciphertext) + 인증 태그(Tag).
  3. 출력:

    • 암호문과 인증 태그를 함께 반환하며, 복호화 시 태그를 검증하여 데이터 무결성을 확인.

주요 매개변수

매개변수 설명 권장값/주의사항
키 길이 AES 암호화에 사용되는 키 크기. 128, 192, 256비트 (256비트 권장).
IV (Nonce) 초기화 벡터로, 암호화마다 고유해야 함. 12바이트(96비트) 권장, 재사용 절대 금지.
AAD 인증에만 사용되는 추가 데이터 (암호화되지 않음). 선택적, 예: 프로토콜 헤더 등.
태그 길이 인증 태그의 길이로, 무결성 검증에 사용. 128비트(기본), 96, 104, 112, 120비트 가능.
Cipher 형식 자바에서 GCM 모드를 지정하는 형식. "AES/GCM/NoPadding" (패딩 불필요).

IV/Nonce에 대한 중요 참고

  • GCM은 IV(Nonce) 재사용 시 보안이 심각하게 손상됩니다. 동일한 키와 IV 조합을 두 번 사용하면 인증 태그가 의미를 잃고, 암호문이 노출될 수 있습니다.
  • 12바이트(96비트) Nonce가 표준으로 권장되며, 더 긴 IV를 사용할 경우 내부적으로 해시 처리됩니다.

자바에서 AES-GCM 사용 예제

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

public class AesGcmExample {
    public static void main(String[] args) throws Exception {
        // 1. AES 키 생성
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256); // 256비트 키
        SecretKey key = keyGen.generateKey();

        // 2. IV (Nonce) 생성
        byte[] iv = new byte[12]; // 12바이트 Nonce
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);

        // 3. 암호화 설정
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec spec = new GCMParameterSpec(128, iv); // 128비트 태그 길이
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);

        // 4. AAD 추가 (선택적)
        byte[] aad = "AuthData".getBytes(StandardCharsets.UTF_8);
        cipher.updateAAD(aad);

        // 5. 암호화
        byte[] plaintext = "Hello, AES-GCM!".getBytes(StandardCharsets.UTF_8);
        byte[] ciphertext = cipher.doFinal(plaintext);

        // 결과 출력
        System.out.println("IV: " + bytesToHex(iv));
        System.out.println("Ciphertext (with tag): " + bytesToHex(ciphertext));

        // 6. 복호화
        cipher.init(Cipher.DECRYPT_MODE, key, spec);
        cipher.updateAAD(aad); // AAD 동일해야 함
        byte[] decrypted = cipher.doFinal(ciphertext);
        System.out.println("Decrypted: " + new String(decrypted, StandardCharsets.UTF_8));
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}

장점

  1. 효율성: 암호화와 인증을 단일 패스로 처리하여 속도가 빠름.
  2. 보안성: 인증 태그로 무결성과 출처 인증을 보장.
  3. 유연성: AAD를 통해 추가 데이터를 인증 가능.

단점 및 주의사항

  1. Nonce 재사용 금지: 동일한 키와 Nonce를 재사용하면 보안이 완전히 무너질 수 있음 (키스트림 재사용 문제).
  2. 태그 길이 조정 시 주의: 짧은 태그(예: 64비트)는 충돌 위험이 증가할 수 있음.
  3. 복잡성: IV 관리와 AAD 처리가 추가적으로 필요.

응용 사례

  • TLS 1.2/1.3: AES-GCM은 TLS에서 널리 사용되는 cipher suite입니다 (예: TLS_AES_256_GCM_SHA384).
  • 디스크 암호화: 인증과 함께 데이터 보호.
  • 메시징 시스템: 메시지 무결성과 기밀성 보장.

AES-GCM은 현대 암호화에서 매우 강력하고 효율적인 선택이지만, IV 관리와 키 회전에 신경 써야 합니다. 추가로 궁금한 점이나 특정 부분에 대한 더 깊은 설명이 필요하면 말씀해주세요!