Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 272 – 블록 암호화 알고리즘용 API v1.0

Author:
A.M. Kuchling <amk at amk.ca>
Status:
Final
Type:
Informational
Created:
18-Sep-2001
Post-History:
17-Apr-2002, 29-May-2002

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

이 문서는 DES나 Rijndael과 같은 비밀키 블록 암호화 알고리즘을 위한 표준 API를 규정하여, 서로 다른 알고리즘과 구현 간의 전환을 더 쉽게 만듭니다.

소개

암호화 알고리즘은 입력 데이터(평문이라고 함)를 가변 키에 의존하는 방식으로 변환하여 암호문을 생성합니다. 이 변환은 키를 알고 있는 경우에 한해서만 쉽게 역변환될 수 있습니다. 키는 가능한 키들로 이루어진 매우 큰 공간에서 선택된 비트들의 시퀀스입니다. 암호화 알고리즘에는 블록 암호와 스트림 암호라는 두 부류가 있습니다.

블록 암호는 고정된 크기(흔히 8바이트 또는 16바이트 길이)의 다중 바이트 입력을 암호화하며, 다양한 피드백 모드로 동작할 수 있습니다. 이 명세에서 지원하는 피드백 모드는 다음과 같습니다.

번호 상수 설명
1 MODE_ECB Electronic Code Book
2 MODE_CBC 암호 블록 체이닝
3 MODE_CFB 암호 피드백
5 MODE_OFB 출력 피드백
6 MODE_CTR 카운터

이 모드들은 NIST 발행물 SP 800-38A [1]에 설명된 대로 구현되어야 합니다. 처음 세 가지 피드백 모드에 대한 설명은 브루스 슈나이어의 저서 Applied Cryptography [2]에서도 찾을 수 있습니다.

(숫자 값 4는 RFC 2440: “OpenPGP Message Format”에 설명된 CFB의 변형인 MODE_PGP를 위해 예약되어 있습니다. 이 모드는 모든 블록 암호화 암호에 대해 요구할 만큼 중요하다고 여겨지지는 않지만, 지원하는 것은 좋은 추가 기능입니다.)

엄밀한 형식적 의미에서, 스트림 암호는 데이터를 비트 단위로 암호화합니다. 실질적으로는 스트림 암호가 문자 단위로 동작합니다. 이 PEP는 블록 암호에 대한 인터페이스를 명시하는 것만을 목표로 하지만, 스트림 암호도 ‘block_size’를 1로 고정함으로써 여기서 설명하는 인터페이스를 지원할 수 있습니다. 피드백 모드 또한 스트림 암호에는 의미가 없으므로, 유일하게 타당한 피드백 모드는 ECB 모드일 것입니다.

명세

암호화 모듈은 이 PEP에서 설명하는 것 이외의 추가적인 함수, 메서드, 속성을 더할 수 있지만, 어떤 모듈이 이 PEP를 준수한다고 주장하려면 이 PEP에서 설명하는 모든 기능이 존재해야 합니다.

비밀키 암호화 모듈은 다음과 같은 함수 하나를 정의해야 합니다:

new(key, mode, [IV], **kwargs)

문자열 ‘key’에 담긴 비밀키를 사용하고, 위 표에 있는 상수 중 하나여야 하는 피드백 모드 ‘mode’를 사용하여, 암호화 객체를 반환합니다.

‘mode’가 MODE_CBC나 MODE_CFB인 경우, ‘IV’가 제공되어야 하며 블록 크기와 같은 길이의 문자열이어야 합니다. ‘IV’의 값을 제공하지 않으면 ValueError 예외가 발생하게 됩니다.

알고리즘에 따라, 모듈은 이 함수에 추가적인 키워드 인자를 지원할 수 있습니다. 일부 키워드 인자는 이 PEP에서 지정하며, 모듈은 자유롭게 추가 키워드 인자를 더할 수 있습니다. 특정 키워드에 값이 제공되지 않은 경우, 안전한 기본값이 사용되어야 합니다. 예를 들어, 어떤 알고리즘이 1에서 16 사이에서 선택 가능한 라운드 수를 가지고 있고, 1라운드 암호화는 안전하지 않지만 8라운드 암호화는 안전하다고 여겨진다면, ‘rounds’의 기본값은 8 이상이어야 합니다. (모듈 구현자는 이 예시에서 16처럼 매우 느리지만 안전한 값을 선택할 수도 있습니다. 이 결정은 구현자에게 맡겨져 있습니다.)

다음 표는 이 PEP에서 정의하는 키워드 인자를 나열합니다:

키워드 의미
counter counter 블록을 반환하는 호출 가능 객체(아래 참조, CTR 모드 전용)
rounds 사용할 암호화 라운드 수
segment_size 비트 단위로 측정된 데이터와 암호문 세그먼트의 크기(아래 참조, CFB 모드 전용)

Counter 피드백 모드는 출력을 생성하는 데 사용되는, counter라고 불리는 입력 블록들의 시퀀스를 필요로 합니다. ‘mode’가 MODE_CTR인 경우, ‘counter’ 키워드 인자가 제공되어야 하며, 그 값은 함수나 메서드와 같은 호출 가능 객체여야 합니다. 이 호출 가능 객체에 대한 연속적인 호출은 ‘block_size’ 길이를 가지며 결코 반복되지 않는 문자열들의 시퀀스를 반환해야 합니다. (NIST 간행물의 부록 B는 그러한 시퀀스를 생성하는 방법을 제시하지만, 이는 본 PEP의 범위를 벗어납니다.)

CFB 모드는 길이가 ‘segment_size’ 비트인 평문과 암호문의 세그먼트에 대해 작동합니다. 따라서 이 모드를 사용할 때, 입력과 출력 문자열의 길이는 ‘segment_size’ 비트의 배수여야 합니다. ‘segment_size’는 1과 block_size*8 사이의(양 끝값 포함) 정수여야 합니다. (8이라는 계수는 ‘block_size’가 비트가 아닌 바이트 단위로 측정되기 때문입니다.) 이 매개변수의 기본값은 block_size*8이어야 합니다. 구현자는 단순성을 위해 ‘segment_size’를 8의 배수로 제한할 수 있지만, 일반성을 위해 임의의 값을 지원하는 것이 권장됩니다.

비밀키 암호화 모듈은 두 개의 변수를 정의해야 합니다:

  • block_size

    정수 값이며, 이 모듈이 암호화하는 블록의 크기를 바이트 단위로 나타냅니다. 모든 피드백 모드에서, encrypt()와 decrypt()에 전달되는 문자열의 길이는 블록 크기의 배수여야 합니다.

  • key_size

    정수 값이며, 이 모듈이 요구하는 키의 크기를 바이트 단위로 나타냅니다. key_size가 None이면, 알고리즘은 가변 길이 키를 받아들입니다. 이는 모듈이 임의의 길이의 키를 받아들인다는 것을 의미할 수도 있고, 가능한 길이가 몇 가지로 정해져 있다는 것을 의미할 수도 있습니다. 예를 들어 16, 24, 32바이트 등입니다. 길이가 0인 키(즉, 널 문자열 ‘’)는 가변 길이 키로 전달할 수 없습니다.

Cipher 객체는 두 개의 속성을 가져야 합니다:

  • block_size

    이 객체가 암호화하는 블록의 크기와 같은 정수 값입니다. 가변 블록 크기를 가진 알고리즘의 경우, 이 값은 이 객체에 대해 선택된 블록 크기와 같습니다.

  • IV

    암호 피드백 모드를 시작하는 데 사용될 초기값을 담고 있으며, 항상 정확히 한 블록 길이의 문자열입니다. 문자열을 암호화하거나 복호화한 후, 이 값은 수정된 피드백 텍스트를 반영하도록 갱신됩니다. 이 값은 읽기 전용이며, 새 값을 대입할 수 없습니다.

Cipher 객체는 다음 메서드들을 요구합니다:

  • decrypt(string)

    객체에 있는 키에 종속된 데이터를 사용하고, 적절한 피드백 모드로 ‘string’을 복호화합니다. 문자열의 길이는 알고리즘의 블록 크기, 또는 CFB 모드에서는 세그먼트 크기의 정확한 배수여야 합니다. 평문을 담은 문자열을 반환합니다.

  • encrypt(string)

    객체에 있는 키에 종속된 데이터를 사용하고, 적절한 피드백 모드로 비어 있지 않은 문자열을 암호화합니다. 문자열의 길이는 알고리즘의 블록 크기, 또는 CFB 모드에서는 세그먼트 크기의 정확한 배수여야 합니다. 암호문을 담은 문자열을 반환합니다.

‘DES’라는 이름의 모듈을 사용하는 예제는 다음과 같습니다.:

>>> import DES
>>> obj = DES.new('abcdefgh', DES.MODE_ECB)
>>> plaintext = "Guido van Rossum is a space alien."
>>> len(plaintext)
34
>>> obj.encrypt(plaintext)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
ValueError: Strings for DES must be a multiple of 8 in length
>>> ciphertext = obj.encrypt(plain+'XXXXXX')   # Add padding
>>> ciphertext
'\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006'
>>> obj.decrypt(ciphertext)
'Guido van Rossum is a space alien.XXXXXX'

참고 문헌

변경 사항

2002-04: 스트림 암호에 대한 참조를 제거함, PEP 제목을 다시 지음, 피드백 모드 상수에 MODE_ 접두사를 붙임, PGP 피드백 모드를 제거함, CTR 및 OFB 피드백 모드를 추가함, 숫자가 바이트 단위로 측정되는 곳과 비트 단위로 측정되는 곳을 명확히 함.

2002-09: 키 길이에 대한 논의에서 “arbitrary-length” 대신 “variable-length keys”를 사용하여 명확히 함.

감사의 말

이 PEP에 대해 의견을 주신 python-crypto 메일링 리스트 독자분들께 감사드립니다.