14.1. "hashlib" --- セキュアハッシュおよびメッセージダイジェスト
****************************************************************

バージョン 2.5 で追加.

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

======================================================================

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

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

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

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

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

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

>>> import hashlib
>>> m = hashlib.md5()
>>> m.update("Nobody inspects")
>>> m.update(" the spammish repetition")
>>> m.digest()
'\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("Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'

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

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

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

このモジュールは以下の定数属性を提供しています:

hashlib.algorithms

   このモジュールによってサポートされていることが保証されるハッシュア
   ルゴリズムの名前が入ったタプル。

   バージョン 2.7 で追加.

hashlib.algorithms_guaranteed

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

   バージョン 2.7.9 で追加.

hashlib.algorithms_available

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

   バージョン 2.7.9 で追加.

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

hash.digest_size

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

hash.block_size

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

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

hash.update(arg)

   文字列 *arg* でハッシュオブジェクトを更新します。繰り返し呼び出すこ
   とは引数全ての連結で一回呼び出すことと等価です。例えば
   "m.update(a); m.update(b)" は "m.update(a+b)" と等価です。

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

hash.digest()

   これまでに "update()" メソッドに渡した文字列のダイジェストを返しま
   す。これは "digest_size" バイトの文字列であり、非ASCII文字やnull バ
   イトを含むこともあります。

hash.hexdigest()

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

hash.copy()

   ハッシュオブジェクトのコピー ("クローン") を返します。これは、共通
   部分を持つ複数の文字列のダイジェストを効率的に計算するために使用し
   ます。


14.1.1. 鍵導出
==============

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

hashlib.pbkdf2_hmac(name, password, salt, rounds, dklen=None)

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

   文字列 *name* は、HMAC のハッシュダイジェストに使いたいアルゴリズム
   の名前で、例えば 'sha1' や 'sha256' です。 *password* と *salt* は
   バイト列のバッファとして解釈されます。アプリケーションとライブラリ
   は *password* に相応しい値 (例えば 1024) に制限すべきです。 *salt*
   は "os.urandom()" のような適切な所源から得た、およそ 16 かそれより
   も多いバイト列でなければなりません。

   *rounds* 数はハッシュアルゴリズムと計算機の能力に基いて決められるべ
   きです。2013 年現在の場合、 SHA-256 に対して最低でも 100,000 ラウン
   ドをお奨めします。

   *dklen* が "None" の場合、ハッシュアルゴリズム *name* のダイジェス
   トサイズが使われます。例えば SHA-512 では 64 です。

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

   バージョン 2.7.8 で追加.

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

参考:

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

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

  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
     FIPS 180-2 のセキュアハッシュアルゴリズムについての説明。

  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 の記事。
