15.1. hashlib — セキュアハッシュおよびメッセージダイジェスト

ソースコード: Lib/hashlib.py


このモジュールは、セキュアハッシュやメッセージダイジェスト用のさまざまなアルゴリズムを実装したものです。FIPSのセキュアなハッシュアルゴリズムである SHA1、SHA224、SHA256、SHA384およびSHA512 (FIPS 180-2 で定義されているもの) だけでなくRSAのMD5アルゴリズム (Internet RFC 1321 で定義されています)も実装しています。「セキュアなハッシュ」と「メッセージダイジェスト」はどちらも同じ意味です。古くからあるアルゴリズムは「メッセージダイジェスト」と呼ばれていますが、最近は「セキュアハッシュ」という用語が用いられています。

注釈

adler32 や crc32 ハッシュ関数は zlib モジュールで提供されています。

警告

幾つかのアルゴリズムはハッシュの衝突に弱いことが知られています。最後の “参考” セクションを見てください。

15.1.1. ハッシュアルゴリズム

hash の名前が付いたコンストラクタがあります。いずれも同一で簡単なインターフェイスのあるハッシュオブジェクトを返します。例えば、SHA1 ハッシュオブジェクトを作るには sha1() を使います。このオブジェクトには update() を用いて bytes-like オブジェクト (通常 bytes) を渡すことができます。digest()hexdigest() メソッドを用いて、それまでに渡したデータを連結したものの digest をいつでも要求することができます。

注釈

マルチスレッドにおける良好なパフォーマンスを得るために、オブジェクトの生成時または更新時に与えるデータが 2047 バイトを超えている場合、Python GIL が解放されます。

注釈

文字列オブジェクトを update() に渡すのはサポートされていません。ハッシュはバイトには機能しますが、文字には機能しないからです。

このモジュールで常に使用できるハッシュアルゴリズムのコンストラクタは md5()sha1()sha224()sha256()sha384() および sha512() です。それ以外のアルゴリズムが使用できるかどうかは、Python が使用している OpenSSL ライブラリに依存します。

たとえば、b'Nobody inspects the spammish repetition' というバイト文字列のダイジェストを取得するには次のようにします:

>>> import hashlib
>>> m = hashlib.md5()
>>> m.update(b"Nobody inspects")
>>> m.update(b" the spammish repetition")
>>> m.digest()
b'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
>>> m.digest_size
16
>>> m.block_size
64

もっと簡潔に書くと、このようになります:

>>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
hashlib.new(name[, data])

一般的なコンストラクタで、第一引数にアルゴリズム名を文字列で受け取ります。他にも、上記ハッシュだけでなく OpenSSL ライブラリーが提供するような他のアルゴリズムにアクセスすることができます。名前のあるコンストラクタの方が new() よりもずっと速いので望ましいです。

new() にOpenSSLのアルゴリズムを指定する例です:

>>> h = hashlib.new('ripemd160')
>>> h.update(b"Nobody inspects the spammish repetition")
>>> h.hexdigest()
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'

Hashlib は以下の定数属性を提供しています:

hashlib.algorithms_guaranteed

このモジュールによってすべてのプラットフォームでサポートされていることが保証されるハッシュアルゴリズムの名前を含む集合です。

バージョン 3.2 で追加.

hashlib.algorithms_available

実行中の Python インタープリタで利用可能なハッシュアルゴリズム名の set です。これらの名前は new() に渡すことができます。algorithms_guaranteed は常にサブセットです。この set の中に同じアルゴリズムが違う名前で複数回現れることがあります (OpenSSL 由来)。

バージョン 3.2 で追加.

コンストラクタが返すハッシュオブジェクトには、次のような定数属性が用意されています:

hash.digest_size

生成されたハッシュのバイト数。

hash.block_size

内部で使われるハッシュアルゴリズムのブロックのバイト数。

ハッシュオブジェクトには次のような属性があります:

hash.name

このハッシュの正規名です。常に小文字で、new() の引数として渡してこのタイプの別のハッシュを生成することができます。

バージョン 3.4 で変更: name 属性は CPython には最初からありましたが、Python 3.4 までは正式に明記されていませんでした。そのため、プラットフォームによっては存在しないかもしれません。

ハッシュオブジェクトには次のようなメソッドがあります:

hash.update(arg)

オブジェクト arg でハッシュオブジェクトを更新します。arg はバイトのバッファとして解釈可能でなければなりません。繰り返し呼び出すことは引数全ての連結で一回呼び出すことと等価です。例えば m.update(a); m.update(b)m.update(a+b) と等価です。

バージョン 3.1 で変更: ハッシュアルゴリズムが OpenSSL によって提供されていて、データが 2047 バイトを超えている場合には、ハッシュの更新が実行中でも他のスレッドが実行できるように、Python GIL が解放されます。

hash.digest()

これまで update() メソッドに渡されたデータのダイジェスト値を返します。これは digest_size と同じ長さの、0 から 255 の範囲全てを含み得るバイトの列です。

hash.hexdigest()

digest() と似ていますが、倍の長さの、16進形式文字列を返します。これは、電子メールなどの非バイナリ環境で値を交換する場合に便利です。

hash.copy()

ハッシュオブジェクトのコピー (“クローン”) を返します。これは、最初の部分文字列が共通なデータのダイジェストを効率的に計算するために使用します。

15.1.2. 鍵導出

鍵の導出 (derivation) と引き伸ばし (stretching) のアルゴリズムはセキュアなパスワードのハッシュ化のために設計されました。 sha1(password) のような甘いアルゴリズムは、ブルートフォース攻撃に抵抗できません。良いパスワードハッシュ化は調節可能で、遅くて、 salt を含まなければなりません。

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

この関数は PKCS#5 のパスワードに基づいた鍵導出関数 2 を提供しています。疑似乱数関数として HMAC を使用しています。

文字列 hash_name は、HMAC のハッシュダイジェストアルゴリズムの望ましい名前で、例えば ‘sha1’ や ‘sha256’ です。 passwordsalt はバイト列のバッファとして解釈されます。アプリケーションとライブラリは、 password を適切な長さ (例えば 1024) に制限すべきです。 saltos.urandom() のような適切なソースからの、およそ 16 バイトかそれ以上のバイト列にするべきです。

iterations 数はハッシュアルゴリズムと計算機の能力に基づいて決めるべきです。2013 年現在の場合、 SHA-256 に対して最低でも 100,000 反復が推奨されています。

dklen は、導出された鍵の長さです。 dklenNone の場合、ハッシュアルゴリズム hash_name のダイジェストサイズが使われます。例えば SHA-512 では 64 です。

>>> import hashlib, binascii
>>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000)
>>> binascii.hexlify(dk)
b'0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5'

バージョン 3.4 で追加.

注釈

pbkdf2_hmac の高速な実装は OpenSSL 使用版で利用可能です。Python 実装は hmac のインラインバージョンを使います。それはおよそ 3 倍遅く、GIL を解放しません。

参考

hmac モジュール

ハッシュを用いてメッセージ認証コードを生成するモジュールです。

base64 モジュール

バイナリハッシュを非バイナリ環境用にエンコードするもうひとつの方法です。

http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf

FIPS 180-2 のセキュアハッシュアルゴリズムについての説明。

https://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms (日本語版: https://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E5%AD%A6%E7%9A%84%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E9%96%A2%E6%95%B0)

どのアルゴリズムにどんな既知の問題があって、それが実際に利用する際にどう影響するかについての Wikipedia の記事。

https://www.ietf.org/rfc/rfc2898.txt
PKCS #5: Password-Based Cryptography Specification Version 2.0