LoginSignup
14
14

More than 5 years have passed since last update.

PHPのmcryptで暗号化、複号化するサンプル

Last updated at Posted at 2016-05-29

概要

PHPの拡張モジュールのphp-mcryptを使って暗号化、復号化をするサンプル。
インストールはこちら
libmcrypt, php-mcrypt をCentOS 6.7にインストール

実行

$ tree
.
├── app.php
├── mcrypt.php

$ php app.php

サンプルコード

app.php
<?php
require_once "./mcrypt.php";

$text = "fizzbazz";
$mcrypt = new Mcrypt;

/*オリジナル*/
echo "Original Text: {$text} \r\n";
# Original Text: fizzbazz 

/*暗号化します*/
$encrypted = $mcrypt->encrypt($text); 
echo "Encrypted: {$encrypted} \r\n";
# Encrypted: KbR8BrizX2KfpMw5G6gxi0B6TLPhkRAShSY106kjO38= 

/*復号化します*/
$decrypted = $mcrypt->decrypt($encrypted);
echo "Decrypted: {$decrypted} \r\n";
# Decrypted: fizzbazz

php-mcryptのラッパークラス

mcrypt.php
<?php

class Mcrypt
{
    const SECRET = "5!47?92977d7fd5c1ALa6b07072c#";

    private $td;
    private $iv;
    private $key;

    private function initialize()
    {
        /* Open the cipher */
        $this->td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');

        /* Create the IV and determine the keysize length*/
        if (!$this->iv) {
            $this->iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_DEV_URANDOM);
        }
        $ks = mcrypt_enc_get_key_size($this->td);

         /* Create key */
        $this->key = substr(hash("sha256", self::SECRET), 0, $ks);
    }

    public function encrypt($input)
    {
        $this->initialize();

        /* Intialize encryption */
        mcrypt_generic_init($this->td, $this->key, $this->iv);

        /* Encrypt data */
        $encrypted = mcrypt_generic($this->td, base64_encode($input));

        $this->finalize();

        return base64_encode($encrypted);
    }

    public function decrypt($encrypted)
    {
        $this->initialize();

        /* Intialize encryption */
        mcrypt_generic_init($this->td, $this->key, $this->iv);

        $encrypted = base64_decode($encrypted, true);

        /* Decrypt encrypted string */
        $decrypted = mdecrypt_generic($this->td, $encrypted);

        $this->finalize();

        return base64_decode($decrypted, true);
    }

    private function finalize()
    {
        /* Terminate handle and close module */
        mcrypt_generic_deinit($this->td);
        mcrypt_module_close($this->td);
    }
}

説明

mcrypt_module_open
暗号化のモジュールを、アルゴリズム、モードを指定してオープンします。
第一引数 algorithmは、MCRYPT_暗号名が使えます。例えば、MCRYPT_RIJNDAEL_256は鍵とブロックの長さが256ビット。AESにも選定されたアルゴリズムなので、今回採用してみました。

第三引数のmodeは、MCRYPT_MODE_(ECBやCBC)となります。
ECBは初期化ベクトル($this->iv)を必要としない、比較的簡単な暗号化モードだそう。異なるサイト間のやり取り等で初期化ベクトルが共有できないケースや、そこまでセキュリティレベルを上げる必要が無い場合は、良いかも。ただし、一回パターンが見破られるとアウト。

CBCは初期化ベクトル($this->iv)がEncrypt,Decrypt時に同じものを指定する必要があります。毎回違うベクトルで暗号化するので、パターンが見破られる事はない。今回はCBCとしたので if (!$this->iv) として、暗号、複号とも同じ初期化ベクトルによって処理するようにしました。別クラスで処理する場合は、$this->ivの値も受渡して、Decryptする必要があります。

mcrypt_create_iv
暗号化のための値を生成します。
これが↑で行っている $this->ivつまりInitial Vectorです。
第一引数のsizeは、mcrypt_enc_get_iv_size で取得可能。
第二引数のsourceは、Linux環境なので /dev/urandom からランダムな値を取得することにしました。

mcrypt_generic_init
mcrypt_generic
mcrypt_generic_deinit
mcrypt_module_close
この辺りは、mcryptの基本の流れになります。
他に、mcrypt-encryptmcrypt-decryptなど↑をラップしたメソッドもありますので、処理を細かく分ける必要が無ければ、こちらも利用可能かと。

参考

http://pentan.info/doc/block_cipher.html
暗号利用モード wikipedia

14
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14