"crypt" --- Unix パスワードをチェックするための関数
***************************************************

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

バージョン 3.11 で非推奨: The "crypt" module is deprecated (see **PEP
594** for details and alternatives). The "hashlib" module is a
potential replacement for certain use cases.

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

このモジュールは修正 DES アルゴリズムに基づいた一方向ハッシュ関数であ
る *crypt(3)*  ルーチンを実装しています。詳細については Unix マニュア
ルページを参照してください。このモジュールは、実際に入力されたパスワー
ドを記録することなくチェック出来るようにするためのハッシュ化パスワード
を記録したり、Unix パスワードに (脆弱性検査のための) 辞書攻撃を試みる
のに使えます。

このモジュールは実行環境の *crypt(3)* の実装に依存しています。そのため
、現在の実装で利用可能な拡張を、このモジュールでもそのまま利用できます
。

利用可能環境: Unix。VxWorksでは使えません。


ハッシュ化方式
==============

バージョン 3.3 で追加.

"crypt" モジュールはハッシュ化方式の一覧を定義しています (すべての方式
がすべてのプラットフォームで使えるわけではありません):

crypt.METHOD_SHA512

   A Modular Crypt Format method with 16 character salt and 86
   character hash based on the SHA-512 hash function.  This is the
   strongest method.

crypt.METHOD_SHA256

   Another Modular Crypt Format method with 16 character salt and 43
   character hash based on the SHA-256 hash function.

crypt.METHOD_BLOWFISH

   Another Modular Crypt Format method with 22 character salt and 31
   character hash based on the Blowfish cipher.

   バージョン 3.7 で追加.

crypt.METHOD_MD5

   Another Modular Crypt Format method with 8 character salt and 22
   character hash based on the MD5 hash function.

crypt.METHOD_CRYPT

   2文字のソルトと13文字のハッシュ値を持つモジュラー暗号形式です。これ
   が最も弱い方式です。


モジュール属性
==============

バージョン 3.3 で追加.

crypt.methods

   利用可能なパスワードのハッシュアルゴリズムのリストを、
   "crypt.METHOD_*" オブジェクトとして返します。 このリストは最も強い
   ものから弱いものの順で並べられています。


モジュール関数
==============

"crypt" モジュールは以下の関数を定義しています:

crypt.crypt(word, salt=None)

   *word* will usually be a user's password as typed at a prompt or
   in a graphical interface.  The optional *salt* is either a string
   as returned from "mksalt()", one of the "crypt.METHOD_*" values
   (though not all may be available on all platforms), or a full
   encrypted password including salt, as returned by this function.
   If *salt* is not provided, the strongest method available in
   "methods" will be used.

   通常は、生の文字列のパスワードを *word* として渡し、前回の
   "crypt()" を呼び出した結果と今回の呼び出しの結果が同じになることで
   、パスワードの確認を行います。

   *salt* (2文字から16文字のランダムな文字列で、方式を示す "$digit$"
   が先頭に付いているかもしれません) は、暗号化アルゴリズムにぶれを生
   じさせるために使われます。 *salt* に含まれる文字は、モジュラー暗号
   形式の先頭にある "$digit$" を除いて、集合 "[./a-zA-Z0-9]" に含まれ
   ていなければいけません。

   ハッシュ化されたパスワードを文字列として返します。それは salt と同
   じアルファベット文字から構成されます。

   いくつかの拡張された *crypt(3)* は異なる値と *salt* の長さを許して
   いるので、パスワードをチェックする際には crypt されたパスワード文字
   列全体を *salt* として渡すよう勧めます。

   バージョン 3.3 で変更: 文字列に加え、 *salt* が "crypt.METHOD_*" 値
   も受け取るようになりました。

crypt.mksalt(method=None, *, rounds=None)

   Return a randomly generated salt of the specified method.  If no
   *method* is given, the strongest method available in "methods" is
   used.

   The return value is a string suitable for passing as the *salt*
   argument to "crypt()".

   *rounds* specifies the number of rounds for "METHOD_SHA256",
   "METHOD_SHA512" and "METHOD_BLOWFISH". For "METHOD_SHA256" and
   "METHOD_SHA512" it must be an integer between "1000" and
   "999_999_999", the default is "5000".  For "METHOD_BLOWFISH" it
   must be a power of two between "16" (2^4) and "2_147_483_648"
   (2^31), the default is "4096" (2^12).

   バージョン 3.3 で追加.

   バージョン 3.7 で変更: Added the *rounds* parameter.


使用例
======

典型的な使い方を簡単な例で示します (タイミング攻撃に晒されないように、
一定時間の比較演算子を使う必要があり、 "hmac.compare_digest()" がこの
目的にちょうど良いです):

   import pwd
   import crypt
   import getpass
   from hmac import compare_digest as compare_hash

   def login():
       username = input('Python login: ')
       cryptedpasswd = pwd.getpwnam(username)[1]
       if cryptedpasswd:
           if cryptedpasswd == 'x' or cryptedpasswd == '*':
               raise ValueError('no support for shadow passwords')
           cleartext = getpass.getpass()
           return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd)
       else:
           return True

利用可能な方式のうち最も強い方式を使いパスワードのハッシュ値を生成し、
元のパスワードと比較してチェックします:

   import crypt
   from hmac import compare_digest as compare_hash

   hashed = crypt.crypt(plaintext)
   if not compare_hash(hashed, crypt.crypt(plaintext, hashed)):
       raise ValueError("hashed version doesn't validate against original")
