CRYPT(3)

名称
crypt - トラップドア暗号化

ライブラリ
libcrypt

書式
<unistd.h> char * crypt(const char *key, const char *salt) const char * crypt_get_format(void) int crypt_set_format(const char *string)

解説
crypt() 関数は、パスワードのハッシュ化を行ない、キー検索の試みを 思いとどまらせるためのコードを付加します。 ハッシュ化には異なるアルゴリズムを使用することができます。 現在含まれるアルゴリズムは、 NBS Data Encryption Standard (DES), MD5, Blowfish です。 DES や Blowfish がインストールされているかどうか、また、 デフォルトを変更するために crypt_set_format() がすでに呼び出されているかどうかにより、 使用されるアルゴリズムは salt (モジュール化暗号フォーマット (Modular Crypt Format (MCF)) に従います) のフォーマットに依存します。

crypt の最初の引数はハッシュ化のためのデータ (通常はパスワードです) で、 ヌル文字で終了する文字列です。 2 番めの引数は salt で、次の 3 個のうちのいずれかの形式です。

Extended
    アンダスコア (“_”) で始まる場合、鍵の解釈も salt の解釈もともに、次に概要を説明する DES 拡張形式を使用します。
Modular
    文字列 “$digit$” で始まる場合、次に概要を説明する モジュール化暗号フォーマット (MCF) を使用します。
Traditional
    上のいずれにも該当しない場合、伝統的なフォーマット (Traditional Format) を想定し、文字列全体 (または最初の部分) を salt として使用します。

どのルーチンも計算に時間が掛かる設計になっています。 Pentium 166/MMX で簡単なテストをすると、 DES 暗号化では、1 CPU 秒当たり暗号化を約 2640 回行ない、 MD5 暗号化では、1 CPU 秒当たり暗号化を約 62 回行ないました。

  DES 拡張形式:

鍵 key は 8 文字からなるグループに分割されます (最後のグループにはナルバイトが 詰められます)。 各キャラクタの下位 7 ビット (グループごとに 56 ビット) が、 次に説明するようにして、 DES キーを作るために用いられます。 最初のグループの 56 ビットは、 DES 鍵の初期値です。 その後のグループごとに、現在の DES 鍵それ自身とそのグループのビットを XOR することで暗号化し、次の DES 鍵とします。

salt は 9 キャラクタの配列であり、アンダスコアの後ろに 4 バイトの 反復回数と 4 バイトの salt からなります。 これらは印字可能文字でエンコードされます。 6 ビットごとに 1 文字を対応させ、最下位キャラクタを最初にして、 エンコードされます。 0 から 63 までの値は ``./0-9A-Za-z'' としてエンコードされます。 これにより count と salt のそれぞれに 24 ビットを使うことができます。

salt は DES アルゴリズムに対し、16777216 通りまたは 4096 通り (つまり、24 ビットまたは 12 ビット) 中の 1 通りという不規則性を導入します ( salt のビット i が設定されている場合、 DES E-Box 出力中の ビット i とビット i+24 とが交換されます) 。

DES 鍵を使い、64ビットの定数に count 回 DES を繰り返し適用し暗号化します。 返される値は、 ヌル文字で終了する 文字列で、長さは 20 バイトまたは 13 バイト (にヌル文字が加わります) で、 salt の後に、エンコードされた 64 ビットの暗号化を続いたもので 構成されます。

  モジュール化暗号:

salt が文字列 $digit$ から始まる場合は、モジュール化暗号フォーマット (MCF) が使用されます。 digit は暗号化の際にどのアルゴリズムが使用されるかを表します。 その後ろのトークンが実際の salt として暗号化に用いられます。 salt の長さは 16 キャラクタに制限されています。 これは、返す出力の長さも _PASSWORD_LEN で制限されているからです。 salt はヌル文字かドル記号を末尾に置く必要があります。 ドル記号の後ろの文字はなんであれ無視されます。

現在サポートするアルゴリズムは、

1.  MD5
2.  Blowfish

これ以外の暗号化フォーマットは容易に追加できます。 salt の例として次のものがあります。

$3$thesalt$rest

  Traditional 暗号化:

使用されるアルゴリズムは、 crypt_set_format() がすでに呼び出されているか否か、グローバルデフォルトフォーマットが すでに指定されているか否かに依存します。 グローバルデフォルトがあらかじめ指定されているか、 crypt_set_format() で何か他のフォーマットを設定されているか、そのどちらでもない場合、 組み込みのデフォルトフォーマットが使用されます。 現在のところ、これは、 DES が使えるなら DES に、そうでないなら MD5 になります。

salt をどのように用いるかはハッシュ化のアルゴリズムに依存します。 最高の結果を得るために、少なくとも 2 文字の salt を指定してください。

crypt_get_format() 関数は現在使用しているアルゴリズムを表す定数文字列を返します。 有効な値は、 ‘des’, ‘blf’, ‘md5’ です。

crypt_set_format() 関数は指定する string に従い、デフォルトエンコードフォーマットを設定します。

グローバルデフォルトフォーマットは、 /etc/auth.conf ファイルで、 crypt_default 属性を使い設定することができます。

戻り値
crypt() は、処理が成功した場合、暗号化された値を指すポインタを返します。 処理が失敗した場合、NULL を返します。 注意: これは通常の挙動ではありません。 AT&T の crypt() は常に文字列を指すポインタを返します。

crypt_set_format() は、与えられたエンコードフォーマットが正当であれば、1 を返します。 それ以外の場合、値 0 が返されます。

関連項目
login(1), passwd(1), auth_getval(3), cipher(3), getpass(3), auth.conf(5), passwd(5)

バグ
crypt() 関数は静的データへのポインタを返します。 そして、以後の crypt() の呼び出しは同じデータを変更します。 crypt_set_format() も同様に静的データを変更します。

歴史
ローターを採用した crypt() 関数は、 AT&T UNIX で登場しました。 現在のスタイルの crypt() は、 AT&T UNIX ではじめて登場しました。

DES セクションのコード (FreeSec 1.0) は、アメリカ合衆国のみで使える NetBSD libcrypt 暗号化ライブラリに対して、そのような障害のない置き換えとして アメリカ合衆国の外で開発されました。

作者
-nosplit 元は David Burren <davidb@werj.com.au> によって書かれました。 その後の追加、更新は、 Poul-Henning Kamp, Mark R V Murray, Kris Kennaway, Brian Feldman, Paul Herman Niels Provos によって行なわれました。