crypt

(PHP 4, PHP 5, PHP 7, PHP 8)

crypt文字列の一方向のハッシュ化を行う

警告

この関数は (まだ)バイナリデータ対応ではありません!

説明

crypt(string $string, string $salt): string

crypt() 文字列のハッシュを返します。 Unix 標準の DES ベースのアルゴリズムか、 代替のアルゴリズムを使用します。 password_verify()crypt() と互換性があるので、 crypt() が作ったパスワードハッシュは password_verify() でも使えます。

salt パラメータは必須ではありませんが、これを省略すると crypt() が作るハッシュが弱いものになってしまいます。 このパラメータを省略した場合には、E_NOTICE が発生します。 十分に強いソルトを指定して、セキュリティを確保しましょう。

password_hash() は、強力なハッシュを使い、強力なソルトを生成して、それを複数回自動的に適用します。 password_hash()crypt() のシンプルなラッパーであり、既存のパスワードハッシュと互換性があります。 password_hash() を使うことを推奨します。

ハッシュ方式は、salt 引数によって決まります。 salt を省略した場合は、標準の 2 文字 (DES) の salt を自動生成します。 あるいは、MD5 crypt() が使えれば 12 文字 (MD5) の salt を自動生成します。 PHP の定数 CRYPT_SALT_LENGTH には、 ハッシュで使用できる salt の最大長が格納されています。

標準の DES ベースの場合、crypt() は出力の最初の 2 文字を salt として使用します。また、 string の最初の 8 文字しか使用しません。 つまり、最初の 8 文字が同じである長い文字列は、 同じ salt を使う限り同じ結果となります。

以下のハッシュ形式がサポートされています:

  • CRYPT_STD_DES - 標準の DES ベースのハッシュで、 アルファベット "./0-9A-Za-z" からなる 2 文字の salt を使用するもの。 salt として無効な文字を使うと crypt() は失敗します。
  • CRYPT_EXT_DES - 拡張した DES ベースのハッシュ。 "salt" は 9 文字で、 アンダースコアの後に 4 文字の反復回数と 4 文字の salt が続きます。 これらの4文字それぞれが、24ビットにエンコードされ、 下位の文字から順に並びます。 0 から 63 までの値は ./0-9A-Za-z の範囲内の文字でエンコードされます。 salt に無効な文字を使うと crypt() は失敗します。
  • CRYPT_MD5 - $1$ ではじまる 12 文字の salt を使用する MD5 ハッシュ。
  • CRYPT_BLOWFISH - Blowfish ハッシュ。salt の形式は、 "$2a$" か "$2x$" あるいは "$2y$"、2 桁のコストパラメータ、"$"、そして文字 "./0-9A-Za-z" からなる 22 文字となります。 この範囲外の文字を salt に使うと、crypt() は長さゼロの文字列を返します。 2 桁のコストパラメータは反復回数の 2 を底とする対数で、 これは Blowfish ベースのハッシュアルゴリズムで使います。 この値は 04 から 31 までの範囲でなければならず、 それ以外の値の場合は crypt() は失敗します。 "$2x$" ハッシュは潜在的に弱いハッシュです。 "$2a$" ハッシュはこれと互換性があり、この弱点を軽減します。 新しくハッシュを生成する場合は、"$2y$" を使うべきです。 セキュリティ修正の対応の詳細については » この文書 を参照ください。
  • CRYPT_SHA256 - SHA-256 ハッシュに $5$ で始まる 16 文字の salt を組み合わせたもの。salt 文字列が 'rounds=<N>$' で始まる場合は、数値 N がハッシュループの実行回数を表します。 これは Blowfish のコストパラメータのようなものです。 rounds のデフォルトは 5000 で、1000 から 999,999,999 までの値を指定できます。 この範囲外の N を指定すると、近い方の境界値に切り詰められます。
  • CRYPT_SHA512 - SHA-512 ハッシュに $6$ で始まる 16 文字の salt を組み合わせたもの。salt 文字列が 'rounds=<N>$' で始まる場合は、数値 N がハッシュループの実行回数を表します。 これは Blowfish のコストパラメータのようなものです。 rounds のデフォルトは 5000 で、1000 から 999,999,999 までの値を指定できます。 この範囲外の N を指定すると、近い方の境界値に切り詰められます。

パラメータ

string

ハッシュしたい文字列。

警告

CRYPT_BLOWFISH を使うと、 string が最大 72 バイトまでに切り詰められます。

salt

ハッシュのもととなる salt 文字列。省略した場合の挙動は アルゴリズムの実装によって決まるので、予期せぬ結果となることがあり得ます。

戻り値

ハッシュした文字列を返します。 失敗した場合は、salt とは異なることが保証されている 13 文字未満の文字列を返します。

警告

パスワードを検証するときの文字列比較関数は、 タイミング攻撃に対して脆弱ではないものでなければいけません。 これをもちいて、crypt() の出力と既知のハッシュとを比較します。 この比較を行うために、hash_equals() 関数が使えます。

変更履歴

バージョン 説明
8.0.0 salt は、オプションではなくなりました。

例1 crypt() の例

<?php
// saltを自動的に生成させます; お勧めできません
$hashed_password crypt('mypassword');


/* 異なったハッシュアルゴリズムが使用された際の問題を避けるために
   crypt()の結果全体をパスワード比較用のsaltとして渡す必要があります。
   (上記のように標準DESに基づくパスワードハッシュは2文字のsaltを使用します
   が、MD5に基づくハッシュは12文字のsaltを使用します) */
if (hash_equals($hashed_passwordcrypt($user_input$hashed_password))) {
   echo 
"Password verified!";
}
?>

例2 crypt() を htpasswd で使用する例

<?php
// パスワードを設定します
$password 'mypassword';

// ハッシュを取得します。salt は自動生成させます; お勧めできません
$hash crypt($password);
?>

例3 異なるハッシュ形式を用いた crypt() の例

<?php
/* これらの salt はあくまでも一例として示したものであり、実際のコードにそのまま使ってはいけません。
   別の、適切な形式の salt を生成して各パスワードに使いましょう。
*/
echo 'Standard DES: ',
    
crypt('rasmuslerdorf''rl'),
    
"\n";
echo 
'Extended DES: ',
    
crypt('rasmuslerdorf''_J9..rasm'),
    
"\n";
echo 
'MD5:          ',
    
crypt('rasmuslerdorf''$1$rasmusle$'),
    
"\n";
echo 
'Blowfish:     ',
    
crypt('rasmuslerdorf''$2a$07$usesomesillystringforsalt$'),
    
"\n";
echo 
'SHA-256:      ',
    
crypt('rasmuslerdorf''$5$rounds=5000$usesomesillystringforsalt$'),
    
"\n";
echo 
'SHA-512:      ',
    
crypt('rasmuslerdorf''$6$rounds=5000$usesomesillystringforsalt$'),
    
"\n";
?>

上の例の出力は、 たとえば以下のようになります。

Standard DES: rl.3StKT.4T8M
Extended DES: _J9..rasmBYk8r9AiWNc
MD5:          $1$rasmusle$rISCgZzpwk3UhDidwXvin0
Blowfish:     $2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi
SHA-256:      $5$rounds=5000$usesomesillystri$KqJWpanXZHKq2BOB43TSaYhEWsQ1Lr5QNyPCDH/Tp.6
SHA-512:      $6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21

注意

注意: 復号するための関数はありません。 crypt() が使用しているのは単方向アルゴリズムだからです。

参考

  • hash_equals() - タイミング攻撃に対して安全な文字列比較
  • password_hash() - パスワードハッシュを作る
  • md5() - 文字列のmd5ハッシュ値を計算する
  • 暗号化関数についての Unix man ページ

関連キーワード:  ハッシュ, salt, 文字, crypt, 一方向, パラメータ, string, hash, rounds, 関数