728x90

 

1. ECB (Electronic Codebook) 모드

  • 방식: 각 블록을 독립적으로 암호화.
  • 특징:
    • 동일한 평문 블록 → 동일한 암호문 블록.
    • 병렬 처리 가능.
  • 단점: 패턴이 반복되면 암호문에도 반복 패턴이 생겨 보안상 위험.
  • 용도: 거의 사용하지 않음 (보안 취약).

도식:

C_i = E(K, P_i)

 

 

 2. CBC (Cipher Block Chaining) 모드

  • 방식: 이전 암호문 블록과 현재 평문 블록을 XOR 후 암호화.
  • 특징:
    • 초기화 벡터(IV)가 필요.
    • 동일한 평문 블록이라도 암호문은 달라짐.
    • 병렬 복호화 가능, 암호화는 직렬 처리.
  • 단점:
    • 하나의 블록 오류 → 현재 블록과 다음 블록 오류 전파.

도식:

C_i = E(K, P_i ⊕ C_{i-1}),  C_0 = IV

 

 

3. CFB (Cipher Feedback) 모드

  • 방식: 이전 암호문 블록을 암호화한 후, 평문과 XOR.
  • 특징:
    • 스트림 암호처럼 동작 가능.
    • 부분 블록 처리 가능.
    • 복호화 시 병렬 처리 어려움.
  • 단점:
    • CBC처럼 오류 전파 발생.

도식:

C_i = P_i ⊕ E(K, C_{i-1}),  C_0 = IV

🔑 4. OFB (Output Feedback) 모드

  • 방식: 암호화기 출력만을 피드백하여 XOR.
  • 특징:
    • 오류 전파 없음 (한 비트 오류 → 해당 비트만 손상).
    • 미리 키 스트림 생성 가능.
    • IV 필수.
  • 단점:
    • IV 재사용 시 보안 치명적.

도식:

O_i = E(K, O_{i-1}),  C_i = P_i ⊕ O_i,  O_0 = IV

 

 

5. CTR (Counter) 모드

  • 방식: 증가하는 카운터 값을 암호화 후, 평문과 XOR.
  • 특징:
    • 완전 병렬 처리 가능 (암호화/복호화 모두).
    • 미리 키 스트림 생성 가능.
    • IV 또는 nonce 필요.
  • 단점:
    • 카운터 값 충돌 → 보안 붕괴.

도식:

C_i = P_i ⊕ E(K, Nonce || Counter_i)

 

 

 

비교 요약

모드병렬 암호화병렬 복호화오류 전파패턴 감춤

운영모드 병렬 암호화 병렬 복호화 오류 전파 패턴 감춤
ECB O O X X
CBC X O O O
CFB X X O O
OFB X X X O
CTR O O X O
오류전파 : 암호문에서 한비트가 손상되었을 대 복호화된 평문에서 얼마나 많은 부분이 잘못되느냐를 의미
패턴감춤 : 평문에 반복되는 패턴(ex. 'AAAA', 'BBBB')이 암호문에서 그대로 드러나는지를 의미

 

선택 포인트

  • 안전성 중요 → ECB는 피하기.
  • 병렬 성능 필요 → CTR 모드.
  • 스트림 암호화 필요 → OFB, CFB.
  • 파일 암호화 → CBC, CTR.

 

728x90
728x90

PKCS#7 패딩 개요

  • 블록 크기: 일반적으로 8바이트(64비트) 또는 16바이트(128비트)
  • 패딩 규칙:
    • 패딩이 필요한 경우: N 바이트를 패딩해야 한다면, N 바이트 모두 N으로 채움
    • 패딩이 필요 없는 경우(블록 크기의 정확한 배수): 전체 블록 크기만큼 패딩 추가 (block_size 바이트 모두 block_size 값으로 채움)

예시 (AES의 16바이트 블록 기준):

  • 원문: YELLOW SUBMARINE (16바이트) → 패딩 추가: 0x10 0x10 ... (16번)
  • 원문: YELLOW SUB (11바이트) → 패딩 추가: 0x05 0x05 0x05 0x05 0x05

 

PKCS#7 패딩 구현

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void pkcs7_pad(unsigned char *input, size_t input_len, size_t block_size,
               unsigned char **output, size_t *output_len) {
    size_t pad_len = block_size - (input_len % block_size);
    *output_len = input_len + pad_len;
    *output = (unsigned char *)malloc(*output_len);
    if (*output == NULL) {
        perror("malloc failed");
        exit(1);
    }

    memcpy(*output, input, input_len);
    memset(*output + input_len, (unsigned char)pad_len, pad_len);
}

int pkcs7_unpad(unsigned char *input, size_t input_len,
                unsigned char **output, size_t *output_len) {
    if (input_len == 0) return -1;

    unsigned char pad_len = input[input_len - 1];

    if (pad_len == 0 || pad_len > input_len) return -1;

    for (size_t i = 0; i < pad_len; ++i) {
        if (input[input_len - 1 - i] != pad_len)
            return -1;  // Invalid padding
    }

    *output_len = input_len - pad_len;
    *output = (unsigned char *)malloc(*output_len);
    if (*output == NULL) {
        perror("malloc failed");
        return -1;
    }

    memcpy(*output, input, *output_len);
    return 0;
}

 

 

 

728x90

+ Recent posts