暗号化・複合化を行う ブロック暗号
PHPでブロック暗号を行うにはMcrypt関数で可能です。
AESやDES、Blowfishなどが使用可能です。
[参考記事] ブロック暗号とは
[参考記事] Javaで暗号化・複合化を行う ブロック暗号
[参考記事] Perlで暗号化・複合化を行う ブロック暗号
[参考記事] Rubyで暗号化・複合化を行う ブロック暗号
PHPではCrypt_BlowfishというPEARもあります。
[参考記事] テキストを可逆的な暗号化する Crypt_Blowfish
サンプルコード
使用できる暗号利用モードの一覧
使用できる暗号アルゴリズムの一覧
Mcrypt関数を使用するにはPHPにmcryptが組み込まれている必要があり、mcryptはlibmcryptを必要とします。
PHP5以降では、libmcrypt2.5.6以降が必要です。
Linuxなどではyumでphp-mcryptパッケージがこれに該当し、yumでのインストールは次のようにします。
yum -y install php-mcrypt
Windowsの場合はPHP 5.2以降でライブラリに組み込まれています。
この暗号化方式はアルゴリズム規定のブロック長に分割して秘密鍵を用いて暗号化を行います。
規定のブロック長に分割する方式を暗号利用モード、ブロック長に満たないときの補完方法をパディング方式といいます。
暗号利用モードで分割するときに前の平文ブロックの結果を次の平文に使用しますが、この最初のブロックで使用される値がIV(初期化ベクトル)です。
まとめ
暗号化の流れ
(1) ブロック長に満たない部分をパディング方式で補完する。
(2) アルゴリズムに対応したブロック長に分割する。
このときの分割ルールを決めるのが暗号利用モード
分割モードによっては初期値が必要で、これがIV(初期化ベクトル)
(3) 暗号鍵を用いてアルゴリズムで暗号化する。
(4) 分割されたデータを結合する。
復号化の流れ
(1) アルゴリズムに対応したブロック長に分割する。
(2) 暗号鍵を用いてアルゴリズムで復号化する。
(3) 暗号利用モードを元に分割されたデータを結合する。
分割モードによっては初期値が必要で、これがIV(初期化ベクトル)
(4) 補完されたパディングをパディング方式で除去する。
ブロック暗号では、
ブロック長
秘密鍵
暗号アルゴリズム
暗号利用モード
パディング方式
IV(初期化ベクトル)
の6つのキーワードが重要です。
使用できる暗号化アルゴリズムは組み込まれているlibmcryptに依存します。
ブロック長、共通鍵の長さは使用する暗号アルゴリズムに依存します。
暗号利用モードにはECB、CBD、OFB、CFBなどが使用できます。
パディング方式はZeroBytePaddingのみです。
パディング不要な状態であればZeroBytePaddingは何もしないので、PKCS#5 Paddingなどは独自に実装することで使用できます。
NoPaddingはできません。
ZeroBytePaddingではブロック長に満たない長さをNULL(0x00)で埋める方式ですが、末尾の0x00が本来生成された値の末尾なのかパディングされた値なのかを判断できないため、使用しないほうがいいです。
サンプルコード
PKCS#5 Paddingでのサンプルです。
// 暗号化を行う function cipher_encrypt($input,$key) { // 指定した暗号のブロックサイズを得る $size = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB); // PKCS5Padding ブロック長に満たないサイズを埋める $input = pkcs5_pad($input, $size); // 使用するアルゴリズムおよびモードのモジュールをオープンする $td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, ''); // オープンされたアルゴリズムの IV の大きさを返す $ivsize = mcrypt_enc_get_iv_size($td); // MCRYPT_RAND の初期化を行う srand(); // 乱数ソースから初期化ベクトル(IV)を生成する // ECB以外では復号にこのIV(初期化ベクトル)が必要です。 // ECBではIVは使用されませんが、IVがないとエラーが出ます。 $iv = mcrypt_create_iv($ivsize, MCRYPT_RAND); // 暗号化に必要な全てのバッファを初期化する mcrypt_generic_init($td, $key, $iv); // データを暗号化する $data = mcrypt_generic($td, $input); // 暗号化モジュールを終了する mcrypt_generic_deinit($td); // mcrypt モジュールを閉じる mcrypt_module_close($td); return $data; } // 複合化を行う function cipher_decrypt($input,$key) { // 指定した暗号のブロックサイズを得る $size = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB); // 使用するアルゴリズムおよびモードのモジュールをオープンする $td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, ''); // オープンされたアルゴリズムの IV の大きさを返す $ivsize = mcrypt_enc_get_iv_size($td); // MCRYPT_RAND の初期化を行う srand(); // 乱数ソースから初期化ベクトル(IV)を生成する // ECB以外では暗号化に用いたIV(初期化ベクトル)が必要です。 // ECBではIVは使用されませんが、IVがないとエラーが出ます。 $iv = mcrypt_create_iv($ivsize, MCRYPT_RAND); // 暗号化に必要な全てのバッファを初期化する mcrypt_generic_init($td, $key, $iv); // データを復号する $data = mdecrypt_generic($td, $input); // 暗号化モジュールを終了する mcrypt_generic_deinit($td); // mcrypt モジュールを閉じる mcrypt_module_close($td); // PKCS5Padding 埋められたバイト値を除く $data = pkcs5_unpad($data, $size); return $data; } // PKCS5Padding // ブロック長に満たないサイズを埋める function pkcs5_pad($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } // PKCS5Padding // 埋められたバイト値を除く function pkcs5_unpad($text) { $pad = ord($text{strlen($text)-1}); if ($pad > strlen($text)) return false; if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false; return substr($text, 0, -1 * $pad); } /****************** 暗号化例 ******************/ // 暗号化するデータ $data = "この文字を暗号化します。"; // 暗号キー $key = "ABCDEF"; echo "元のデータ : " . $data; echo "<br />"; $encrypt = cipher_encrypt($data,$key); echo "暗号化されたデータ : " . $encrypt; echo "<br />"; $decrypt = cipher_decrypt($encrypt,$key); echo "複合化されたデータ : " . $decrypt;
使用できる暗号利用モードの一覧
MCRYPT_MODE_ECB | electronic codebook | 他のキーを暗号化するといったランダムデータに適しています。出力データが短くランダムであるというECBの短所は、都合の良い逆の効果を持っています。 |
---|---|---|
MCRYPT_MODE_CBC | cipher block chaining | 特に、ECB よりも著しく高いセキュリティでファイルを暗号化する用途に適しています。 |
MCRYPT_MODE_CFB | cipher feedback | 1 バイト毎に暗号化する必要があるバイトストリームを暗号化する際に最も適したモードです。 |
MCRYPT_MODE_OFB | output feedback、8 ビット形式 | CFBと互換性が ありますが、エラーの伝播が許容されないアプリケーションに使用することが可能です。このモードは(8 ビットモードで処理を行うため)安全ではなく、使用は推奨されません。 |
MCRYPT_MODE_NOFB | output feedback、nビット形式 | OFBと互換ですが、アルゴリズムのブロックサイズを変更可能なため、より安全です。 |
MCRYPT_MODE_STREAM | "WAKE" や "RC4" のようないくつかのストリームアルゴリズムを読み込む追加のモードです。 |
使用できる暗号アルゴリズムの一覧
MCRYPT_3DES
MCRYPT_ARCFOUR_IV (libmcrypt > 2.4.x のみ)
MCRYPT_ARCFOUR (libmcrypt > 2.4.x のみ)
MCRYPT_BLOWFISH
MCRYPT_CAST_128
MCRYPT_CAST_256
MCRYPT_CRYPT
MCRYPT_DES
MCRYPT_DES_COMPAT (libmcrypt 2.2.x のみ)
MCRYPT_ENIGMA (libmcrypt > 2.4.x のみ、MCRYPT_CRYPT へのエイリアス)
MCRYPT_GOST
MCRYPT_IDEA (非フリー)
MCRYPT_LOKI97 (libmcrypt > 2.4.x のみ)
MCRYPT_MARS (libmcrypt > 2.4.x のみ、非フリー)
MCRYPT_PANAMA (libmcrypt > 2.4.x のみ)
MCRYPT_RIJNDAEL_128 (libmcrypt > 2.4.x のみ)
MCRYPT_RIJNDAEL_192 (libmcrypt > 2.4.x のみ)
MCRYPT_RIJNDAEL_256 (libmcrypt > 2.4.x のみ)
MCRYPT_RC2
MCRYPT_RC4 (libmcrypt 2.2.x のみ)
MCRYPT_RC6 (libmcrypt > 2.4.x のみ)
MCRYPT_RC6_128 (libmcrypt 2.2.x のみ)
MCRYPT_RC6_192 (libmcrypt 2.2.x のみ)
MCRYPT_RC6_256 (libmcrypt 2.2.x のみ)
MCRYPT_SAFER64
MCRYPT_SAFER128
MCRYPT_SAFERPLUS (libmcrypt > 2.4.x のみ)
MCRYPT_SERPENT(libmcrypt > 2.4.x のみ)
MCRYPT_SERPENT_128 (libmcrypt 2.2.x のみ)
MCRYPT_SERPENT_192 (libmcrypt 2.2.x のみ)
MCRYPT_SERPENT_256 (libmcrypt 2.2.x のみ)
MCRYPT_SKIPJACK (libmcrypt > 2.4.x のみ)
MCRYPT_TEAN (libmcrypt 2.2.x のみ)
MCRYPT_THREEWAY
MCRYPT_TRIPLEDES (libmcrypt > 2.4.x のみ)
MCRYPT_TWOFISH (古い mcrypt 2.x 系か、あるいは mcrypt > 2.4.x )
MCRYPT_TWOFISH128 (TWOFISHxxx は 2.x の新しいバージョンで使用可能ですが、2.4.x では使用できません)
MCRYPT_TWOFISH192
MCRYPT_TWOFISH256
MCRYPT_WAKE (libmcrypt > 2.4.x のみ)
MCRYPT_XTEA (libmcrypt > 2.4.x のみ)
関連記事
- PHPでwebサーバー(apache/nginx)の実行ユーザー・グループを確認する方法
- リクエストヘッダーやリクエストボディーなどを取得する方法
- 負荷が高いときには503エラーを返す方法
- サイトの更新情報をPINGサーバに送信する方法
- PHPでロードアベレージを表示させる方法
- PHPでTwitterのツイートをする/ツイート一覧を取得する/検索する(API v1.1)
- インクルードパスを設定する方法
- オブジェクト(Object)を配列(Array)に変換する方法
- PHPでgzip圧縮形式(gz圧縮)のファイルを読み書きする方法
- PHPでfacebook投稿時に公開範囲を指定する方法
- PHPで複数の画像をfacebookに投稿する方法
- PHPでfacebookのフィード(ウォール)に投稿する方法
- PHPでのfacebookアプリの認証処理(APIを使うユーザー認証)
- MySQL関数のまとめ
- MySQLサーバに接続できるかどうかを確認する
- ディレクトリ内のファイルのパーミッションを一括で変更する
- POSTでアップロードできるファイルサイズの制限を変更する方法
- date型やdatetime型と年月日時分秒への変換
- 関数・メソッドの存在を調べる方法
- PHPでTwitterのbotを作る方法 ツイートをする/ツイート一覧を取得する(API v1)
- strtotimeの指定
- PHPでHTMLメールを送る方法
- ディレクトリセパレータを短く定義する DIRECTORY_SEPARATOR
- モザイク画像を作る方法
- HTML内のアクセス解析タグを除去する方法
- HTMLのTABLEタグを簡単にCSVファイルに変換する方法
- 画像表示のときに指定サイズにリサイズする(画像の拡大縮小)
- テキストを可逆的な暗号化する Crypt_Blowfish
- PHPでwhois検索をする Net_Whois
- よく使うヘッダー関数のまとめ
- キャリア・世代を判別する
- mb_send_mailでCCやBCCを指定する 表示名を指定する
- より高速に、推測困難な一意なIDを生成する方法
- 画像ファイルを指定容量ぎりぎりに圧縮する
- 指定したHTTPヘッダーが送信済みあるいは送信予定に含まれているか
- DOCUMENT ROOTを得る $_SERVER["DOCUMENT_ROOT"]は使えない!
- マルチバイト文字列(日本語文字)を一文字づつ取り出す
- ファイルを削除する/フォルダを削除する
- ファイルを読み込む/ファイルに書き込む
- ディレクトリ内のファイル一覧を取得する
- quoted-printable文字列の変換
スポンサーリンク