# `hashlib` — Secure hashes and message digests

소스 코드: Lib/hashlib.py

This module implements a common interface to many different secure hash and message digest algorithms. Included are the FIPS secure hash algorithms SHA1, SHA224, SHA256, SHA384, SHA512, (defined in the FIPS 180-4 standard), the SHA-3 series (defined in the FIPS 202 standard) as well as RSA’s MD5 algorithm (defined in internet RFC 1321). The terms “secure hash” and “message digest” are interchangeable. Older algorithms were called message digests. The modern term is secure hash.

참고

adler32나 crc32 해시 함수를 원한다면, `zlib` 모듈에 있습니다.

## 해시 알고리즘

There is one constructor method named for each type of hash. All return a hash object with the same simple interface. For example: use `sha256()` to create a SHA-256 hash object. You can now feed this object with bytes-like objects (normally `bytes`) using the `update` method. At any point you can ask it for the digest of the concatenation of the data fed to it so far using the `digest()` or `hexdigest()` methods.

To allow multithreading, the Python GIL is released while computing a hash supplied more than 2047 bytes of data at once in its constructor or `.update` method.

Constructors for hash algorithms that are always present in this module are `sha1()`, `sha224()`, `sha256()`, `sha384()`, `sha512()`, `sha3_224()`, `sha3_256()`, `sha3_384()`, `sha3_512()`, `shake_128()`, `shake_256()`, `blake2b()`, and `blake2s()`. `md5()` is normally available as well, though it may be missing or blocked if you are using a rare “FIPS compliant” build of Python. These correspond to `algorithms_guaranteed`.

Additional algorithms may also be available if your Python distribution’s `hashlib` was linked against a build of OpenSSL that provides others. Others are not guaranteed available on all installations and will only be accessible by name via `new()`. See `algorithms_available`.

경고

Some algorithms have known hash collision weaknesses (including MD5 and SHA1). Refer to Attacks on cryptographic hash algorithms and the hashlib-seealso section at the end of this document.

Added in version 3.6: SHA3 (Keccak) and SHAKE constructors `sha3_224()`, `sha3_256()`, `sha3_384()`, `sha3_512()`, `shake_128()`, `shake_256()` were added. `blake2b()` and `blake2s()` were added.

버전 3.9에서 변경: 모든 hashlib 생성자는 기본값이 `True`인 키워드 전용 인자 usedforsecurity를 취합니다. 값이 거짓이면 제한된 환경에서 안전하지 않고 차단된 해싱 알고리즘 사용을 허락합니다. `False`는 해싱 알고리즘이 보안 문맥에서 사용되지 않음을 나타냅니다, 예를 들어 암호화가 아닌 단방향 압축 함수로.

버전 3.9에서 변경: Hashlib now uses SHA3 and SHAKE from OpenSSL if it provides it.

버전 3.12에서 변경: For any of the MD5, SHA1, SHA2, or SHA3 algorithms that the linked OpenSSL does not provide we fall back to a verified implementation from the HACL* project.

## Usage

To obtain the digest of the byte string `b"Nobody inspects the spammish repetition"`:

    >>> import hashlib
    >>> m = hashlib.sha256()
    >>> m.update(b"Nobody inspects")
    >>> m.update(b" the spammish repetition")
    >>> m.digest()
    b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7\xfd\xdf\xf7\xbcN\x84:\xa6\xaf\x0c\x95\x0fK\x94\x06'
    >>> m.hexdigest()
    '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

더 압축하면:

    >>> hashlib.sha256(b"Nobody inspects the spammish repetition").hexdigest()
    '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

## Constructors

hashlib.new(name, [data, ]*, usedforsecurity=True)

  Is a generic constructor that takes the string name of the desired algorithm as its first parameter. It also exists to allow access to the above listed hashes as well as any other algorithms that your OpenSSL library may offer.

Using `new()` with an algorithm name:

    >>> h = hashlib.new('sha256')
    >>> h.update(b"Nobody inspects the spammish repetition")
    >>> h.hexdigest()
    '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

hashlib.md5([data, ]*, usedforsecurity=True)

hashlib.sha1([data, ]*, usedforsecurity=True)

hashlib.sha224([data, ]*, usedforsecurity=True)

hashlib.sha256([data, ]*, usedforsecurity=True)

hashlib.sha384([data, ]*, usedforsecurity=True)

hashlib.sha512([data, ]*, usedforsecurity=True)

hashlib.sha3_224([data, ]*, usedforsecurity=True)

hashlib.sha3_256([data, ]*, usedforsecurity=True)

hashlib.sha3_384([data, ]*, usedforsecurity=True)

hashlib.sha3_512([data, ]*, usedforsecurity=True)

Named constructors such as these are faster than passing an algorithm name to `new()`.

## Attributes

Hashlib provides the following constant module attributes:

hashlib.algorithms_guaranteed

  모든 플랫폼에서 이 모듈이 지원하도록 보장된 해시 알고리즘의 이름을 포함하는 집합. ‘md5’는 일부 업스트림 공급자가 이를 제외하는 이상한 “FIPS 호환” 파이썬 빌드를 제공하지만, 이 목록에 있음에 유의하십시오.

  Added in version 3.2.

hashlib.algorithms_available

  실행 중인 파이썬 인터프리터에서 사용 가능한 해시 알고리즘의 이름이 포함된 집합. 이 이름들은 `new()`에 전달될 때 인식됩니다. `algorithms_guaranteed`는 항상 부분 집합입니다. 이 집합에서 같은 알고리즘이 다른 이름으로 여러 번 나타날 수 있습니다 (OpenSSL 덕분입니다).

  Added in version 3.2.

## Hash Objects

다음 값은 생성자가 반환한 해시 객체의 상수 어트리뷰트로 제공됩니다:

hash.digest_size

  결과 해시의 바이트 단위의 크기.

hash.block_size

  해시 알고리즘의 바이트 단위의 내부 블록 크기.

해시 객체에는 다음과 같은 어트리뷰트가 있습니다:

hash.name

  이 해시의 규범적 이름, 항상 소문자이며 항상 이 유형의 다른 해시를 만들기 위한 `new()`에 대한 매개 변수로 적합합니다.

  버전 3.4에서 변경: name 어트리뷰트는 처음부터 CPython에 존재했지만, 파이썬 3.4 이전에는 공식적으로 지정되지 않아서, 일부 플랫폼에는 존재하지 않을 수 있습니다.

해시 객체에는 다음과 같은 메서드가 있습니다:

hash.update(data)

  바이트열류 객체로 해시 객체를 갱신합니다. 반복되는 호출은 모든 인자를 이어붙인 단일 호출과 동등합니다: `m.update(a); m.update(b)`는 `m.update(a+b)`와 동등합니다.

hash.digest()

  지금까지 `update()` 메서드에 전달된 데이터의 요약을 반환합니다. 이것은 `digest_size` 크기의 바이트열 객체이며 0에서 255까지의 전체 범위에 있는 바이트를 포함할 수 있습니다.

hash.hexdigest()

  `digest()`와 유사하지만, 요약은 16진수 숫자만 포함하는 두 배 길이의 문자열 객체로 반환됩니다. 전자 메일이나 기타 바이너리가 아닌 환경에서 값을 안전하게 교환하는 데 사용할 수 있습니다.

hash.copy()

  해시 객체의 사본(“복제본”)을 반환합니다. 이것은 공통된 초기 부분 문자열을 공유하는 데이터의 요약을 효율적으로 계산하는 데 사용될 수 있습니다.

## SHAKE 가변 길이 요약

hashlib.shake_128([data, ]*, usedforsecurity=True)

hashlib.shake_256([data, ]*, usedforsecurity=True)

`shake_128()`과 `shake_256()` 알고리즘은 length_in_bits//2 (최대 128이나 256) 비트의 보안성으로 가변 길이 요약을 제공합니다. 따라서 digest 메서드에는 길이(length)가 필요합니다. 최대 길이는 SHAKE 알고리즘에 의해 제한되지 않습니다.

shake.digest(length)

  Return the digest of the data passed to the `update()` method so far. This is a bytes object of size length which may contain bytes in the whole range from 0 to 255.

shake.hexdigest(length)

  Like `digest()` except the digest is returned as a string object of double length, containing only hexadecimal digits. This may be used to exchange the value in email or other non-binary environments.

Example use:

    >>> h = hashlib.shake_256(b'Nobody inspects the spammish repetition')
    >>> h.hexdigest(20)
    '44709d6fcb83d92a76dcb0b668c98e1b1d3dafe7'

## File hashing

The hashlib module provides a helper function for efficient hashing of a file or file-like object.

hashlib.file_digest(fileobj, digest, /)

  Return a digest object that has been updated with contents of file object.

  fileobj must be a file-like object opened for reading in binary mode. It accepts file objects from builtin `open()`, `BytesIO` instances, SocketIO objects from `socket.socket.makefile()`, and similar. The function may bypass Python’s I/O and use the file descriptor from `fileno()` directly. fileobj must be assumed to be in an unknown state after this function returns or raises. It is up to the caller to close fileobj.

  digest must either be a hash algorithm name as a str, a hash constructor, or a callable that returns a hash object.

  Example:

      >>> import io, hashlib, hmac
      >>> with open(hashlib.__file__, "rb") as f:
      ...     digest = hashlib.file_digest(f, "sha256")
      ...
      >>> digest.hexdigest()
      '...'

      >>> buf = io.BytesIO(b"somedata")
      >>> mac1 = hmac.HMAC(b"key", digestmod=hashlib.sha512)
      >>> digest = hashlib.file_digest(buf, lambda: mac1)

      >>> digest is mac1
      True
      >>> mac2 = hmac.HMAC(b"key", b"somedata", digestmod=hashlib.sha512)
      >>> mac1.digest() == mac2.digest()
      True

  Added in version 3.11.

## 키 파생

키 파생(key derivation)과 키 확장(key stretching) 알고리즘은 안전한 암호 해싱을 위해 설계되었습니다. `sha1(password)`와 같은 순진한 알고리즘은 무차별 대입 공격에 내성이 없습니다. 올바른 암호 해싱 함수는 조정할 수 있고, 느리고, 솔트(salt)를 포함해야 합니다.

hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)

  이 함수는 PKCS#5 암호 기반 키 파생 함수 2를 제공합니다. 의사 난수 함수로 HMAC을 사용합니다.

  문자열 hash_name은 원하는 HMAC을 위한 해시 요약 알고리즘의 이름입니다, 예를 들어 ‘sha1’이나 ‘sha256’. password와 salt는 바이트 버퍼로 해석됩니다. 응용 프로그램과 라이브러리는 password를 적당한 길이(예를 들어 1024)로 제한해야 합니다. salt는 적절한 소스(예를 들어 `os.urandom()`)로부터 온 약 16이나 그 이상의 바이트여야 합니다.

  The number of iterations should be chosen based on the hash algorithm and computing power. As of 2022, hundreds of thousands of iterations of SHA-256 are suggested. For rationale as to why and how to choose what is best for your application, read Appendix A.2.2 of NIST-SP-800-132. The answers on the stackexchange pbkdf2 iterations question explain in detail.

  dklen is the length of the derived key in bytes. If dklen is `None` then the digest size of the hash algorithm hash_name is used, e.g. 64 for SHA-512.

      >>> from hashlib import pbkdf2_hmac
      >>> our_app_iters = 500_000  # Application specific, read above.
      >>> dk = pbkdf2_hmac('sha256', b'password', b'bad salt' * 2, our_app_iters)
      >>> dk.hex()
      '15530bba69924174860db778f2c6f8104d3aaf9d26241840c8c4a641c8d000a9'

  Function only available when Python is compiled with OpenSSL.

  Added in version 3.4.

  버전 3.12에서 변경: Function now only available when Python is built with OpenSSL. The slow pure Python implementation has been removed.

hashlib.scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64)

  이 함수는 RFC 7914에 정의된 대로 scrypt 암호 기반 키 파생 함수를 제공합니다.

  password와 salt는 바이트열류 객체여야 합니다. 응용 프로그램과 라이브러리는 password를 적당한 길이(예를 들어 1024)로 제한해야 합니다. salt는 적절한 소스(예를 들어 `os.urandom()`)로부터 온 약 16이나 그 이상의 바이트여야 합니다.

  n is the CPU/Memory cost factor, r the block size, p parallelization factor and maxmem limits memory (OpenSSL 1.1.0 defaults to 32 MiB). dklen is the length of the derived key in bytes.

  Added in version 3.6.

## BLAKE2

BLAKE2는 RFC 7693에 정의된 암호화 해시 함수로, 두 가지 방식으로 제공됩니다:

- BLAKE2b, 64비트 플랫폼에 최적화되어 있으며 1에서 64바이트 사이의 모든 크기의 요약을 생성합니다,

- BLAKE2s, 8비트에서 32비트 플랫폼에 최적화되어 있으며 1에서 32바이트 사이의 모든 크기의 요약을 생성합니다.

BLAKE2는 키 모드(keyed mode) (HMAC의 더 빠르고 간단한 대체), 솔트 해싱(salted hashing), 개인화(personalization) 및 트리 해싱(tree hashing)을 지원합니다.

이 모듈의 해시 객체는 표준 라이브러리의 `hashlib` 객체의 API를 따릅니다.

### 해시 객체 만들기

생성자 함수를 호출하여 새 해시 객체를 만듭니다:

hashlib.blake2b(data=b'', *, digest_size=64, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)

hashlib.blake2s(data=b'', *, digest_size=32, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)

이 함수는 BLAKE2b나 BLAKE2s를 계산하기위한 해당 해시 객체를 반환합니다. 선택적으로 다음과 같은 일반 매개 변수를 취합니다:

- data: 해시 할 초기 데이터 청크, 바이트열류 객체여야 합니다. 위치 인자로만 전달될 수 있습니다.

- digest_size: 바이트 단위의 출력 요약 크기.

- key: 키 해싱을 위한 키 (BLAKE2b의 경우 최대 64바이트, BLAKE2s의 경우 최대 32바이트).

- salt: 무작위 해싱을 위한 솔트 (BLAKE2b의 경우 최대 16바이트, BLAKE2s의 경우 최대 8바이트).

- person: 개인화 문자열 (BLAKE2b의 경우 최대 16바이트, BLAKE2s의 경우 최대 8바이트).

다음 표는 일반 매개 변수의 제한(바이트 단위)을 보여줍니다:

해시 | digest_size | len(key) | len(salt) | len(person)
--- | --- | --- | --- | ---
BLAKE2b | 64 | 64 | 16 | 16
BLAKE2s | 32 | 32 | 8 | 8

참고

BLAKE2 명세는 솔트와 개인화 매개 변수에 대해 상수 길이를 정의하지만, 편의상, 이 구현에서는 지정된 길이까지 모든 크기의 바이트 문자열을 받아들입니다. 매개 변수의 길이가 지정된 길이보다 작으면, 0으로 채워지므로, 예를 들어 `b'salt'`와 `b'salt\x00'`은 같은 값입니다. (key의 경우에는 해당하지 않습니다.)

이 크기는 아래 설명된 모듈 상수로 제공됩니다.

생성자 함수는 다음 트리 해싱 매개 변수도 받아들입니다:

- fanout: 팬아웃 (0에서 255, 무제한이면 0, 순차적 모드(sequential mode)이면 1).

- depth: 트리의 최대 깊이 (1에서 255, 무제한이면 255, 순차적 모드이면 1).

- leaf_size: maximal byte length of leaf (0 to `2**32-1`, 0 if unlimited or in sequential mode).

- node_offset: node offset (0 to `2**64-1` for BLAKE2b, 0 to `2**48-1` for BLAKE2s, 0 for the first, leftmost, leaf, or in sequential mode).

- node_depth: 노드 깊이 (0에서 255, 리프나 순차적 모드이면 0).

- inner_size: 내부 요약 크기 (BLAKE2b의 경우 0에서 64, BLAKE2s의 경우 0에서 32, 순차적 모드이면 0).

- last_node: boolean indicating whether the processed node is the last one (`False` for sequential mode).

See section 2.10 in BLAKE2 specification for comprehensive review of tree hashing.

### 상수

blake2b.SALT_SIZE

blake2s.SALT_SIZE

솔트 길이 (생성자가 허용하는 최대 길이).

blake2b.PERSON_SIZE

blake2s.PERSON_SIZE

개인화 문자열 길이 (생성자가 허용하는 최대 길이).

blake2b.MAX_KEY_SIZE

blake2s.MAX_KEY_SIZE

최대 키 크기.

blake2b.MAX_DIGEST_SIZE

blake2s.MAX_DIGEST_SIZE

해시 함수가 출력할 수 있는 최대 요약 크기.

### 예

#### 간단한 해싱

To calculate hash of some data, you should first construct a hash object by calling the appropriate constructor function (`blake2b()` or `blake2s()`), then update it with the data by calling `update()` on the object, and, finally, get the digest out of the object by calling `digest()` (or `hexdigest()` for hex-encoded string).

    >>> from hashlib import blake2b
    >>> h = blake2b()
    >>> h.update(b'Hello world')
    >>> h.hexdigest()
    '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

줄여서, 첫 번째 데이터 청크를 위치 인자로 생성자에 전달하여 직접 갱신할 수 있습니다:

    >>> from hashlib import blake2b
    >>> blake2b(b'Hello world').hexdigest()
    '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

해시를 반복적으로 갱신하는 데 필요한 만큼 `hash.update()`를 호출할 수 있습니다:

    >>> from hashlib import blake2b
    >>> items = [b'Hello', b' ', b'world']
    >>> h = blake2b()
    >>> for item in items:
    ...     h.update(item)
    ...
    >>> h.hexdigest()
    '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

#### 다른 요약 크기 사용하기

BLAKE2는 BLAKE2b의 경우 최대 64바이트, BLAKE2s의 경우 최대 32바이트까지 요약 크기를 구성할 수 있습니다. 예를 들어, 출력 크기를 변경하지 않고 SHA-1을 BLAKE2b로 바꾸려면, BLAKE2b에 20바이트 요약을 생성하도록 지시할 수 있습니다:

    >>> from hashlib import blake2b
    >>> h = blake2b(digest_size=20)
    >>> h.update(b'Replacing SHA1 with the more secure function')
    >>> h.hexdigest()
    'd24f26cf8de66472d58d4e1b1774b4c9158b1f4c'
    >>> h.digest_size
    20
    >>> len(h.digest())
    20

요약 크기가 다른 해시 객체의 출력은 완전히 다릅니다 (짧은 해시는 긴 해시의 접두사가 아닙니다); BLAKE2b와 BLAKE2s는 출력 길이가 같더라도 다른 출력을 생성합니다:

    >>> from hashlib import blake2b, blake2s
    >>> blake2b(digest_size=10).hexdigest()
    '6fa1d8fcfd719046d762'
    >>> blake2b(digest_size=11).hexdigest()
    'eb6ec15daf9546254f0809'
    >>> blake2s(digest_size=10).hexdigest()
    '1bf21a98c78a1c376ae9'
    >>> blake2s(digest_size=11).hexdigest()
    '567004bf96e4a25773ebf4'

#### 키 해싱

Keyed hashing can be used for authentication as a faster and simpler replacement for Hash-based message authentication code (HMAC). BLAKE2 can be securely used in prefix-MAC mode thanks to the indifferentiability property inherited from BLAKE.

이 예는 키 `b'pseudorandom key'`로 메시지 `b'message data'`에 대한 (16진 인코딩된) 128비트 인증 코드를 얻는 방법을 보여줍니다:

    >>> from hashlib import blake2b
    >>> h = blake2b(key=b'pseudorandom key', digest_size=16)
    >>> h.update(b'message data')
    >>> h.hexdigest()
    '3d363ff7401e02026f4a4687d4863ced'

실용적인 예로, 웹 응용 프로그램은 사용자에게 전송된 쿠키에 대칭적으로 서명한 후 나중에 변조되지 않았는지 확인할 수 있습니다:

    >>> from hashlib import blake2b
    >>> from hmac import compare_digest
    >>>
    >>> SECRET_KEY = b'pseudorandomly generated server secret key'
    >>> AUTH_SIZE = 16
    >>>
    >>> def sign(cookie):
    ...     h = blake2b(digest_size=AUTH_SIZE, key=SECRET_KEY)
    ...     h.update(cookie)
    ...     return h.hexdigest().encode('utf-8')
    >>>
    >>> def verify(cookie, sig):
    ...     good_sig = sign(cookie)
    ...     return compare_digest(good_sig, sig)
    >>>
    >>> cookie = b'user-alice'
    >>> sig = sign(cookie)
    >>> print("{0},{1}".format(cookie.decode('utf-8'), sig))
    user-alice,b'43b3c982cf697e0c5ab22172d1ca7421'
    >>> verify(cookie, sig)
    True
    >>> verify(b'user-bob', sig)
    False
    >>> verify(cookie, b'0102030405060708090a0b0c0d0e0f00')
    False

네이티브 키 해싱 모드가 있더라도, 물론 BLAKE2를 `hmac` 모듈을 사용하여 HMAC 구성에 사용할 수 있습니다:

    >>> import hmac, hashlib
    >>> m = hmac.new(b'secret key', digestmod=hashlib.blake2s)
    >>> m.update(b'message')
    >>> m.hexdigest()
    'e3c8102868d28b5ff85fc35dda07329970d1a01e273c37481326fe0c861c8142'

#### 무작위 해싱

salt 매개 변수를 설정하면 해시 함수에 무작위화를 도입할 수 있습니다. 무작위 해싱은 디지털 서명에 사용된 해시 함수에 대한 충돌 공격(collision attacks)을 방지하는 데 유용합니다.

> 무작위 해싱은 한 당사자(메시지 준비자)가 두 번째 당사자(메시지 서명자)가 서명할 메시지의 전부나 일부를 생성하는 상황을 위해 설계되었습니다. 메시지 준비자가 암호화 해시 함수 충돌(즉, 같은 해시값을 생성하는 두 메시지)을 찾을 수 있으면, 같은 해시값과 디지털 서명을 생성하는 의미 있는 메시지 버전을 준비할 수 있지만, 결과는 다릅니다 (예를 들어, 계정으로 $10 대신에 $1,000,000을 이체하는 행위). 암호화 해시 함수는 주요 목표로 충돌 내성을 갖도록 설계되었지만, 현재 암호화 해시 함수 공격에 대한 집중으로 인해 주어진 암호화 해시 함수가 예상보다 적은 충돌 내성을 제공할 수 있습니다. 무작위 해싱은 준비자가 디지털 서명 생성 프로세스 동안 궁극적으로 같은 해시값을 산출하는 두 개 이상의 메시지를 생성할 가능성을 줄여서, 서명자에게 추가적인 보호를 제공합니다 – 설사 해시 함수의 충돌을 찾는 것이 실용적이더라도. 그러나, 무작위 해싱을 사용하면 메시지의 모든 부분을 서명자가 준비할 때 디지털 서명이 제공하는 보안의 양을 줄일 수 있습니다.

> (NIST SP-800-106 “Randomized Hashing for Digital Signatures”)

BLAKE2에서 솔트는 각 압축 함수에 대한 입력이 아니라 초기화 중에 해시 함수에 대한 일회성 입력으로 처리됩니다.

경고

Salted hashing (or just hashing) with BLAKE2 or any other general-purpose cryptographic hash function, such as SHA-256, is not suitable for hashing passwords. See BLAKE2 FAQ for more information.

    >>> import os
    >>> from hashlib import blake2b
    >>> msg = b'some message'
    >>> # Calculate the first hash with a random salt.
    >>> salt1 = os.urandom(blake2b.SALT_SIZE)
    >>> h1 = blake2b(salt=salt1)
    >>> h1.update(msg)
    >>> # Calculate the second hash with a different random salt.
    >>> salt2 = os.urandom(blake2b.SALT_SIZE)
    >>> h2 = blake2b(salt=salt2)
    >>> h2.update(msg)
    >>> # The digests are different.
    >>> h1.digest() != h2.digest()
    True

#### 개인화

때로는 해시 함수가 다른 목적으로 같은 입력에 대해 다른 요약을 생성하도록 강제하는 것이 유용합니다. Skein 해시 함수의 저자를 인용합니다:

> 모든 응용 프로그램 설계자는 이렇게 하는 것을 진지하게 고려하도록 권장합니다; 우리는 유사하거나 관련된 데이터에 대해 두 해시 계산이 수행되었기 때문에, 프로토콜의 한 부분에서 계산된 해시가 완전히 다른 부분에서 사용될 수 있는 프로토콜을 많이 보았으며, 공격자는 응용 프로그램이 해시 입력을 갖게 만들도록 강제할 수 있습니다. 프로토콜에 사용된 각 해시 함수를 개인화하면 이러한 유형의 공격이 중단됩니다.

> (The Skein Hash Function Family, p. 21)

BLAKE2는 바이트열을 person 인자에 전달하여 개인화할 수 있습니다:

    >>> from hashlib import blake2b
    >>> FILES_HASH_PERSON = b'MyApp Files Hash'
    >>> BLOCK_HASH_PERSON = b'MyApp Block Hash'
    >>> h = blake2b(digest_size=32, person=FILES_HASH_PERSON)
    >>> h.update(b'the same content')
    >>> h.hexdigest()
    '20d9cd024d4fb086aae819a1432dd2466de12947831b75c5a30cf2676095d3b4'
    >>> h = blake2b(digest_size=32, person=BLOCK_HASH_PERSON)
    >>> h.update(b'the same content')
    >>> h.hexdigest()
    'cf68fb5761b9c44e7878bfb2c4c9aea52264a80b75005e65619778de59f383a3'

키 모드와 함께 개인화를 사용하여, 한 키에서 다른 키들을 파생시킬 수도 있습니다.

    >>> from hashlib import blake2s
    >>> from base64 import b64decode, b64encode
    >>> orig_key = b64decode(b'Rm5EPJai72qcK3RGBpW3vPNfZy5OZothY+kHY6h21KM=')
    >>> enc_key = blake2s(key=orig_key, person=b'kEncrypt').digest()
    >>> mac_key = blake2s(key=orig_key, person=b'kMAC').digest()
    >>> print(b64encode(enc_key).decode('utf-8'))
    rbPb15S/Z9t+agffno5wuhB77VbRi6F9Iv2qIxU7WHw=
    >>> print(b64encode(mac_key).decode('utf-8'))
    G9GtHFE1YluXY1zWPlYk1e/nWfu0WSEb0KRcjhDeP/o=

#### 트리 모드

다음은 두 개의 리프 노드를 갖는 최소 트리를 해싱하는 예입니다:

      10
     /  \
    00  01

이 예는 64바이트 내부 요약을 사용하고, 32바이트 최종 요약을 반환합니다:

    >>> from hashlib import blake2b
    >>>
    >>> FANOUT = 2
    >>> DEPTH = 2
    >>> LEAF_SIZE = 4096
    >>> INNER_SIZE = 64
    >>>
    >>> buf = bytearray(6000)
    >>>
    >>> # Left leaf
    ... h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH,
    ...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
    ...               node_offset=0, node_depth=0, last_node=False)
    >>> # Right leaf
    ... h01 = blake2b(buf[LEAF_SIZE:], fanout=FANOUT, depth=DEPTH,
    ...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
    ...               node_offset=1, node_depth=0, last_node=True)
    >>> # Root node
    ... h10 = blake2b(digest_size=32, fanout=FANOUT, depth=DEPTH,
    ...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
    ...               node_offset=0, node_depth=1, last_node=True)
    >>> h10.update(h00.digest())
    >>> h10.update(h01.digest())
    >>> h10.hexdigest()
    '3ad2a9b37c6070e374c7a8c508fe20ca86b6ed54e286e93a0318e95e881db5aa'

### 크레딧

BLAKE2는 Jean-Philippe Aumasson, Luca Henzen, Willi Meier 및 Raphael C.-W. Phan이 만든 SHA-3 파이널리스트 BLAKE를 기반으로 Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O’Hearn 및 Christian Winnerlein이 설계했습니다.

Daniel J. Bernstein이 설계한 ChaCha 암호(cipher)의 핵심 알고리즘을 사용합니다.

표준 라이브러리 구현은 pyblake2 모듈에 기반합니다. 이것은 Samuel Neves가 작성한 C 구현을 기반으로 Dmitry Chestnykh가 작성했습니다. 이 설명서는 pyblake2에서 복사했으며 Dmitry Chestnykh가 작성했습니다.

C 코드는 Christian Heimes가 파이썬 용으로 부분적으로 재작성했습니다.

다음 공개 도메인 기부는 C 해시 함수 구현, 확장 코드 및 이 설명서 모두에 적용됩니다:

> 법률에 따라 가능한 범위 내에서, 저자(들)는 이 소프트웨어에 대한 모든 저작권과 관련되고 둘러싼 권리를 전 세계 공개 도메인에 기부했습니다. 이 소프트웨어는 보증 없이 배포됩니다.

> 이 소프트웨어와 함께 CC0 Public Domain Dedication의 사본을 받았어야 합니다. 그렇지 않으면, https://creativecommons.org/publicdomain/zero/1.0/ 을 참조하십시오.

다음과 같은 사람들은 Creative Commons Public Domain Dedication 1.0 Universal에 따라 개발을 돕거나 프로젝트와 공개 도메인에 변경에 기여했습니다:

- Alexandr Sokolovskiy

더 보기

모듈 `hmac`

  해시를 사용하여 메시지 인증 코드를 생성하는 모듈.

모듈 `base64`

  바이너리가 아닌 환경을 위해 바이너리 해시를 인코딩하는 다른 방법.

https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.180-4.pdf

  The FIPS 180-4 publication on Secure Hash Algorithms.

https://csrc.nist.gov/pubs/fips/202/final

  The FIPS 202 publication on the SHA-3 Standard.

https://www.blake2.net/

  공식 BLAKE2 웹 사이트.

https://en.wikipedia.org/wiki/Cryptographic_hash_function

  어떤 알고리즘에 알려진 문제가 있고 그것이 사용에 어떤 의미가 있는지에 대한 정보가 포함된 위키피디아 기사.

https://www.ietf.org/rfc/rfc8018.txt

  PKCS #5: Password-Based Cryptography Specification Version 2.1

https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf

  NIST Recommendation for Password-Based Key Derivation.