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

Python 개선 제안 한국어 번역

PEP 452 – 암호화 해시 함수 API v2.0

Author:
A.M. Kuchling <amk at amk.ca>, Christian Heimes <christian at python.org>
Status:
Final
Type:
Informational
Created:
15-Aug-2013
Post-History:

Replaces:
247

Table of Contents

번역·라이선스 안내

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

초록

MD5나 SHA 같은 암호화 해시 알고리즘을 구현한 여러 모듈이 있습니다. 이 문서는 서로 다른 구현 사이를 쉽게 전환할 수 있도록 이러한 알고리즘에 대한 표준 API를 명세합니다.

명세

모든 해시 모듈은 같은 인터페이스를 제공해야 합니다. 메서드나 변수를 추가할 수는 있지만, 이 문서에서 설명하는 것은 항상 있어야 합니다.

해시 함수 모듈은 함수 하나를 정의합니다:

new([string])            (unkeyed hashes)

new(key, [string], [digestmod])    (keyed hashes)
새 해시 객체를 생성하여 반환합니다. 첫 번째 형태는 MD5나 SHA처럼 키가 없는 해시를 위한 것입니다. HMAC처럼 키가 있는 해시에서 ‘key’는 사용할 키를 담은 문자열을 받는 필수 매개변수입니다. 두 경우 모두, 선택적인 ‘string’(문자열) 매개변수가 주어지면 obj.update(string)이 호출된 것처럼 객체의 시작 상태에 즉시 해시됩니다.

해시 객체를 생성한 후에는 객체의 update() 메서드로 임의의 바이트를 객체에 넣을 수 있으며, 객체의 digest() 메서드를 호출하면 언제든지 해시값을 얻을 수 있습니다.

매개변수 이름이 ‘string’(문자열)이지만, 해싱 객체는 8비트 데이터만 다룹니다. ‘key’와 ‘string’(문자열)은 모두 바이트열류 객체(bytes, bytearray…)여야 합니다. 해시 객체는 1차원의 연속 버퍼도 인자로 지원할 수 있습니다. Python 3.x에서는 텍스트(유니코드)를 더 이상 지원하지 않습니다. Python 2.x 구현은 ASCII로만 된 유니코드를 인자로 받을 수도 있지만, 이식성 있는 코드는 이 기능에 의존해서는 안 됩니다.

이 함수에 키워드 인자를 임의로 더 추가할 수 있지만, 그 인자가 주어지지 않으면 합리적인 기본값을 사용해야 합니다. 예를 들어 라운드 수를 바꿀 수 있고 여러 출력 크기를 지원하는 해시 함수라면 ‘rounds’와 ‘digest_size’ 키워드를 추가할 수 있으며, 이 키워드들의 기본값은 안전하다고 여겨지는 값이어야 합니다.

해시 함수 모듈은 변수 하나를 정의합니다:

digest_size
정수값입니다. 이 모듈이 생성한 해싱 객체가 만들어 내는 다이제스트의 크기를 바이트 단위로 나타냅니다. 샘플 객체를 생성하고 그 객체의 ‘digest_size’ 속성에 접근해서 이 값을 얻을 수도 있지만, 이 값을 모듈에서 바로 얻을 수 있으면 편리할 수 있습니다. 출력 크기가 가변적인 해시는 이 변수를 None으로 설정합니다.

해시 객체에는 다음 속성이 있어야 합니다:

digest_size
이 속성은 모듈 수준의 digest_size 변수와 같으며, 해시 객체가 만드는 다이제스트의 크기를 바이트 단위로 나타냅니다. 해시의 출력 크기가 가변적이면 해시 객체를 생성할 때 이 출력 크기를 정해야 하며, 이 속성에는 정한 크기가 들어 있어야 합니다. 따라서 None은 이 속성에 쓸 수 있는 값이 아닙니다.
block_size
정수 값 또는 NotImplemented; 해시 알고리즘의 내부 블록 크기로, 바이트 단위입니다. HMAC 모듈은 블록 크기를 사용하여 비밀 키를 digest_size에 맞게 채우거나, 비밀 키가 digest_size보다 길면 비밀 키를 해시합니다. 해시 알고리즘에 대해 표준화된 HMAC 알고리즘이 없다면, 대신 NotImplemented를 반환하십시오.
name
텍스트 문자열 값; 해싱 알고리즘의 정식 소문자 이름입니다. 이름은 hashlib.new에 적합한 매개변수여야 합니다.

해싱 객체에는 다음 메서드가 필요합니다:

copy()
이 해싱 객체의 별도 사본을 반환합니다. 이 사본을 갱신해도 원본 객체에는 영향을 주지 않습니다.
digest()
이 해싱 객체의 해시 값을 8비트 데이터를 담은 bytes로 반환합니다. 이 함수는 객체를 어떤 식으로도 변경하지 않으므로, 이 함수를 호출한 후에도 객체를 계속 갱신할 수 있습니다.
hexdigest()
이 해싱 객체의 해시 값을 16진수 숫자로 이루어진 문자열로 반환합니다. 숫자 ‘a’부터 ‘f’까지는 소문자를 사용해야 합니다. .digest() 메서드와 마찬가지로, 이 메서드는 객체를 변경해서는 안 됩니다.
update(string)
바이트열류 ‘string’(문자열)을 해싱 객체의 현재 상태에 해시합니다. update()는 해싱 객체의 수명 동안 몇 번이든 호출할 수 있습니다.

해싱 모듈은 추가적인 모듈 수준 함수나 객체 메서드를 정의하더라도 여전히 이 명세를 준수할 수 있습니다.

다음은 ‘MD5’라는 이름의 모듈을 사용한 예입니다:

>>> import hashlib
>>> from Crypto.Hash import MD5
>>> m = MD5.new()
>>> isinstance(m, hashlib.CryptoHash)
True
>>> m.name
'md5'
>>> m.digest_size
16
>>> m.block_size
64
>>> m.update(b'abc')
>>> m.digest()
b'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'
>>> m.hexdigest()
'900150983cd24fb0d6963f7d28e17f72'
>>> MD5.new(b'abc').digest()
b'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'

근거

해시 알고리즘의 크기는 보통 비트 단위로 표기되지만, 다이제스트 크기는 비트가 아닌 바이트 단위로 측정합니다. 예를 들어, MD5는 16바이트 알고리즘이 아니라 128비트 알고리즘입니다. 이는 제가 살펴본 예제 코드에서 바이트 단위의 길이는 자주 필요한 반면(파일에서 앞이나 뒤로 탐색하거나, 출력 문자열의 길이를 계산하기 위해), 비트 단위의 길이는 거의 사용되지 않기 때문입니다. 따라서 그 부담은 실제로 비트 단위의 크기가 필요한 소수의 사람들에게 돌아가며, 이들은 digest_size에 8을 곱해야 합니다.

update() 메서드의 이름을 append()로 하는 것이 더 낫다는 제안이 있었습니다. 하지만 이 메서드는 실제로 해싱 객체의 현재 상태를 갱신하는 것이고, update()는 이미 Python에 포함된 md5와 sha 모듈에서 사용되고 있으므로, update()라는 이름을 그대로 두는 것이 가장 간단해 보입니다.

키가 있는 해시에서 생성자 인자의 순서는 까다로운 문제였습니다. 키가 첫 번째에 와야 하는지 두 번째에 와야 하는지 명확하지 않았습니다. 이것은 필수 매개변수이며, 필수 매개변수를 앞에 두는 것이 일반적인 관례이지만, 그렇게 하면 ‘string’(문자열) 매개변수가 첫 번째 위치에서 두 번째 위치로 옮겨지게 됩니다. 키가 없는 해시에 초기 문자열을 전달한다고 착각하여 키가 있는 해시에 인자 하나만 전달하는 혼동이 생길 수도 있지만, 이러한 잠재적 오류를 피하려고 키가 있는 해시의 인터페이스를 더 모호하게 만들 가치는 없어 보입니다.

버전 1.0에서 버전 2.0으로의 변경 사항

암호 해시 함수용 API 버전 2.0은 API의 일부 측면을 명확히 하고 최신 상태로 갱신합니다. 또한 이미 사실상의 표준으로 자리 잡아 대부분의 구현에서 제공하던 측면들을 공식화했습니다.

버전 2.0에서는 다음과 같은 새 속성이 도입됩니다:

name
name 프로퍼티는 issue 18532에 의해 필수가 되었습니다.
block_size
새 버전은 또한 반환값 NotImplemented가 HMAC 지원을 막는다는 점을 명시합니다.

버전 2.0은 Python 3.0에서 이루어진 바이너리 데이터와 텍스트 데이터의 분리를 고려합니다. new()와 update()에 전달하는 ‘string’(문자열) 인자와 ‘key’ 인자는 바이트열류 객체여야 합니다. Python 2.x에서는 해싱 객체가 ASCII 전용 유니코드도 지원할 수 있습니다. 인자의 실제 이름은 공개 API의 일부이므로 변경되지 않습니다. 코드가 해당 인자의 이름이 ‘string’(문자열)이라는 사실에 의존할 수 있습니다.

일반적인 해싱 알고리즘에 권장되는 이름

algorithm variant recommended name
MD5 md5
RIPEMD-160 ripemd160
SHA-1 sha1
SHA-2 SHA-224 sha224
SHA-256 sha256
SHA-384 sha384
SHA-512 sha512
SHA-3 SHA-3-224 sha3_224
SHA-3-256 sha3_256
SHA-3-384 sha3_384
SHA-3-512 sha3_512
WHIRLPOOL whirlpool

변경 사항

  • 2001-09-17: clear()를 reset()으로 이름을 바꾸었습니다. 객체에 digest_size 속성을 추가하였습니다. .hexdigest() 메서드를 추가하였습니다.
  • 2001-09-20: reset() 메서드를 완전히 제거했습니다.
  • 2001-09-28: 가변 크기 해시에 대해 digest_size를 None으로 설정했습니다.
  • 2013-08-15: block_size와 name 속성을 추가했습니다. ‘string’(문자열)이 실제로는 바이트열류 객체를 가리킨다는 점을 명확히 했습니다.

감사의 글

이 PEP에 의견을 주신 Aahz, Andrew Archibald, Rich Salz, Itamar Shtull-Trauring, 그리고 python-crypto 메일링 리스트의 독자 여러분께 감사드립니다.