개요

블록암호 운용모드 및 운용모드를 이해하는데 필요한 기초 지식을 정리한다.

사전지식: XOR 연산

XOR 은 두 비트의 값이 같으면 0을, 다르면 1을 리턴한다.

XOR 진리표

  1 0
1 0 1
0 1 0

왜 현대의 암호 알고리즘들은 XOR을 사용하는 것인가?

예전부터 가지고 있던 궁금증이다. 내 나름대로 납득한 것을 정리한다.

예를 들어, 다음을 본다. 10101 비트열을 10111 비트열과 XOR하는 예다.

  10101
xor 10111
결과 00010
  • 10101 비트열을 10111 비트열과 XOR하면 00010 이 된다.
  00010
xor 10111
결과 10101
  • 여기서 00010 을 다시 10111 비트열과 XOR하면 10101 이 된다. 원래값으로 돌아왔다!
  • 10101 을 평문이라고 하면 10111 은 키가 되고 00010은 암호문이 된다.
  • 수식으로 표현하면 (P⊕K)⊕K=P다. (어떤 평문값P를 어떤 키의값 K로 XOR 한 결과를, 다시 K로 XOR하면 평문 값P를 구할 수 있다.)
  • XOR을 이용하면 암호화/복호화를 쉽게 구현할 수 있다. 다른 논리 연산자로는 못하는 것이다. 이 것이 암호 알고리즘에서 XOR이 자주 쓰이는 이유라고 생각한다.

사전지식: 패딩

패딩은 평문의 마지막 블록에서 블록 사이즈에 비해 모자란 부분을 채워주는 값이다. 예를 들어 블록 사이즈가 8바이트이고, 평문이 5바이트라면 3바이트를 패딩으로 채워주는 식이다. 다양한 운용모드 중에서 ECB, CBC 모드가 패딩을 사용한다. (이 모드들은 평문의 크기가 블록 사이즈의 배수여야 한다는 규칙이 있기 때문에 패딩을 사용한다.)

PKCS#7

패딩은 여러가지 종류가 있지만 블록 암호에서는 대부분 PKCS#7 를 사용한다. 다음 그림이 8바이트 블록 암호화에서 패딩의 개념을 보여주고 있다. PKCS#7 패딩의 규칙은 패딩의 개수(바이트수)와 그 값이 일치해야 한다는 것이다. 예를 들어 패딩이 한 개일 경우는 패딩의 값도 0x01, 패딩이 두 개인 경우는 패딩의 값도 0x02 여야한다. 평문의 크기가 블록 크기와 동일한 경우를 어떨까? 그림에서 Ex4를 보면 8바이트 블록과 동일한 사이즈인 경우 8개의 패딩이 추가되는 것을 볼 수 있다. 이 것으로 평문과 블록이 동일한 사이즈인 경우에도 패딩이 추가된다는 것을 알 수 있다.

블록암호 패딩예시
https://blog.gdssecurity.com/labs/2010/9/14/automated-padding-oracle-attacks-with-padbuster.html

ECB (Electronic Codebook) 모드

Electronic Code Book 의 약자로 평문을 블록으로 나눠서 각 블록을 암호화하는 방식이다. 간단하기 때문에 이해하기 쉽다.

이미지 출처: ECB 모드 암호화
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

ECB 모드 복호화
en.wikipedia.org/wiki/Block_cipher_mode_of_operation

각 블록이 독립적이므로 병행처리가 가능해 속도는 빠르지만 암호강도가 낮아서 사용하면 안되는 방식이다. 실제로 이미지를 ECB 모드로 암호화했을 경우 다음과 같이 이미지의 윤곽이 그대로 보이게 된다. 이 것으로 ECB 모드의 암호화 강도는 낮다는 것을 알 수 있다.

ECB 모드 이미지

CBC (Cipher Block Chaining) 모드

Cipher Block Chaining 의 약자로 이전의 평문 블록의 암호결과와 다음 평문블록을 XOR한 결과를 암호화하는 방식이다. 1976년 IBM이 개발하였고, 첫번째 블록의 암호화에는 초기화 벡터(Initial Vector, IV)가 쓰인다. 초기화 벡터는 첫번째 블록의 입력 값으로 쓰이다. 초기화 벡터가 같은 경우 출력 결과가 항상 같기 때문에, 매 암호화마다 다른 초기화 벡터를 사용해야 한다. 암호의 강도가 높고, 널리 사용되고 있는 방식이다.

CBC 모드의 암호화 과정
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

CBC 모드의 암호화 과정:

  1. 이니셜벡터(IV)와 초기블록평문 값이 XOR 된다.
  2. 1의 값이 암호화된다.
  3. 2의 값과 두번째 블록의 평문 값이 XOR된다.
  4. 3이 값이 암호화된다.

위 과정을 모든 평문을 암호화할 때까지 반복한다.

CBC 모드의 복호화 과정
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

CBC모드의 복호화 과정:

  1. 첫번째 블록의 암호문을 복호화한 뒤에 이니셜 벡터와 XOR한 값을 구한다.
  2. 두번째 블록의 암호문을 복호화한 뒤에 이전 블록의 암호문과 XOR한 값을 구한다.

위 과정을 모든 암호문을 복호화할 때까지 반복한다.

CBC는 암호화 시에, 입력 값이 이전 결과에 의존하기 때문에 병렬화가 불가능하다. 하지만 복호화의 경우 각 블록을 복호화한 다음 이전 암호화 블록과 XOR하여 복구할 수 있기 때문에 병렬화가 가능하다. (이전 암호화 블록은 이미 가지고 있는 값이다!)

CFB (Cipher Feedback) 모드

CFB 모드 사이에서도 몇 가지 종류가 존재한다.

Full-block CFB

암호 피드백(cipher feedback, CFB) 방식은 CBC의 변형으로, 블록 암호를 자기 동기 스트림 암호로 변환한다. CFB의 동작 방식은 CBC와 비슷하며, 특히 CFB 암호 해제 방식은 CBC 암호화의 역순과 거의 비슷하다.

왜 암호 “피드백” 모드라는 이름이 붙었나? 예상컨대, 복호화 시에 복호화 함수가 아닌 암호화 함수를 사용하기 때문인 것 같다.

CFB 암호화 과정:

CFB모드는 패딩을 이용하지 않는다. CFB모드의 암호화 과정을 살펴보면 먼저 IV를 암호키를 이용해 암호화 한 뒤에 평문과 XOR해서 블록암호문을 구한다. 평문이 나중에 XOR에 이용되기 때문에, 패딩이 있건 없건 동일한 블록사이즈의 결과가 나온다. 따라서 패딩이 필요없다.

CFB 복호화 과정: 복호화 시에 복호화 함수가 아닌 암호화 함수를 사용한다. encryption 이 굵은 글자로 표시된 것으로 보라.

OFB (Output Feedback) 모드

출력 피드백(output feedback, OFB)은 블록 암호를 동기식 스트림 암호로 변환한다.

XOR 명령의 대칭 때문에 암호화와 암호 해제 방식은 완전히 동일하다. OFB모드에서도 평문은 암호화함수를 거친 후에 이용되기 때문에 패딩이 필요없다.

CTR (Counter) 모드

카운터(Counter, CTR) 방식은 블록 암호를 스트림 암호로 바꾸는 구조를 가진다. 카운터 방식에서는 각 블록마다 현재 블록이 몇 번째인지 값을 얻어, 그 숫자와 nonce를 결합하여 블록 암호의 입력으로 사용한다. 그렇게 각 블록 암호문에서 연속적인 난수를 얻은 다음 암호화하려는 문자열과 XOR한다.

CFB, OFB, CTR모드는 는 CBC의 단점(패딩을 이용한다는 단점)을 극복한 것이다.

참고

  • 한글 위키피디아 배타적논리합: https://ko.wikipedia.org/wiki/%EB%B0%B0%ED%83%80%EC%A0%81_%EB%85%BC%EB%A6%AC%ED%95%A9
  • 한글 위키피디아 블록암호운용방식: https://ko.wikipedia.org/wiki/%EB%B8%94%EB%A1%9D_%EC%95%94%ED%98%B8%EC%9A%B4%EC%9A%A9%EB%B0%A9%EC%8B%9D
  • 영문 위키피디아 블록암호운용방식 (가장 자세하다): https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  • https://velog.io/@sem/%EC%A0%95%EB%B3%B4-%EB%B3%B4%EC%95%88-%EB%B8%94%EB%A1%9D-%EC%95%94%ED%98%B8-%EB%AA%A8%EB%93%9C