3v4l.org

run code in 300+ PHP versions simultaneously
<?php class CodeBook { /** PKCS#5でパディング */ const PAD_PKCS5 = 'PAD_PKCS5'; /** Null文字でパディング */ const PAD_NULL = "\0"; /** スペースでパディング */ const PAD_SPACE = ' '; private $_cipher; private $_mode; private $_padding; /** * コンストラクタ * デフォルトは、AES(ブロック長128bit)、CBCモード、PKCS#5でパディング * @param string $cipher (省略可)暗号アルゴリズム * @param string $mode (省略可)暗号モード * @param string $padding (省略可)パディング方法(このクラスの定数 or 文字) * @see http://www.php.net/manual/ja/mcrypt.ciphers.php * @see http://www.php.net/manual/ja/mcrypt.constants.php */ public function __construct($cipher = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_CBC, $padding = self::PAD_PKCS5) { $this->_cipher = $cipher; $this->_mode = $mode; $this->_padding = $padding; } /** * 暗号化する * 初期化ベクトル(IV)を渡さない場合、ランダムな初期化ベクトルを生成する * @param string $key 暗号鍵 * @param string $encryptee 暗号化するデータ * @param string $iv (省略可)初期化ベクトル(ECBでは不要) * @return array hex化した暗号化済みデータと、hex化した初期化ベクトル(IV) */ public function encrypt($key, $encryptee, $iv = null) { $this->_checkKeySize($key); if (!$iv) { $iv = $this->_getRandIv(); } if ($this->_padding === self::PAD_PKCS5) { $encryptee = $this->padPkcs5($encryptee); } else { $encryptee = $this->pad($encryptee, $this->_padding); } $bin = mcrypt_encrypt($this->_cipher, $key, $encryptee, $this->_mode, $iv); return array(bin2hex($bin), bin2hex($iv)); } /** * 復号する * @param string $key 暗号鍵 * @param string $encrypted 暗号化されてhex化されたデータ * @param string $iv (省略可)hex化した初期化ベクトル(ECBでは不要) * @return string 復号したデータ */ public function decrypt($key, $encrypted, $iv = null) { $this->_checkKeySize($key); $bin = $this->hex2bin($encrypted); if ($iv) { $iv = $this->hex2bin($iv); } else { $iv = $this->_getRandIv(); //Warningを出さないためのダミーのIV } $decrypted = mcrypt_decrypt($this->_cipher, $key, $bin, $this->_mode, $iv); if ($this->_padding === self::PAD_PKCS5) { $decrypted = $this->trimPkcs5($decrypted); } else { $decrypted = rtrim($decrypted, $this->_padding); } return $decrypted; } /** * ブロック長に合わせてパディングする * @param string $data パディング対象のデータ * @param string $padChar パディング文字 * @return string パディングしたデータ */ public function pad($data, $padChar) { $size = $this->_getBlockSize(); return str_pad($data, ceil(strlen($data) / $size) * $size, $padChar); } /** * PKCS#5でパディングする * @param string $data パディング対象のデータ * @return string パディングしたデータ */ public function padPkcs5($data) { $size = $this->_getBlockSize(); $padLen = $size - (strlen($data) % $size); return $data . str_repeat(chr($padLen), $padLen); } /** * PKCS#5のパディングを除去する * @param string $data PKCS#5でパディングされたデータ * @return string パディングしたデータ */ public function trimPkcs5($data) { return substr($data, 0, ord(substr($data, -1, 1)) * -1); } /** * hex化したデータをバイナリに変換する(bin2hex()の反対) * @param string $hex hex化されたデータ * @return string バイナリになったデータ */ public function hex2bin($hex) { return pack('H*', $hex); } /** * 暗号鍵の長さをチェックする * @param string $key 暗号鍵 * @throws Exception 長さが不正な場合に例外を投げる */ private function _checkKeySize($key) { $sizes = mcrypt_module_get_supported_key_sizes($this->_cipher); //可変の場合は空なのでチェックしない if ($sizes && !in_array(strlen($key), $sizes)) { throw new Exception("Invalid key length ($key)"); } } /** * ランダムな初期化ベクトル(IV)を生成する * @return string 生成した初期化ベクトル */ private function _getRandIv() { srand(); return mcrypt_create_iv($this->_getBlockSize(), MCRYPT_RAND); } /** * 暗号アルゴリズムと暗号モードに応じたブロックサイズを取得する * @return integer ブロックサイズ */ private function _getBlockSize() { return mcrypt_get_iv_size($this->_cipher, $this->_mode); } } $key = '秘密の鍵128b'; $text = '秘密のメッセージ'; /* AES(RIJNDAEL128)、CBC、PKCS#5でPAD */ $codeBook = new CodeBook(); list($encrypted, $iv) = $codeBook->encrypt($key, $text); //暗号化 $decrypted = $codeBook->decrypt($key, $encrypted, $iv); //復号 // => "秘密のメッセージ => (略) => 秘密のメッセージ" echo $text . ' => ' . $encrypted . ' => ' . $decrypted; echo '<br />'; echo var_dump($text === $decrypted); // => bool(true) echo '<hr />'; /* RIJNDAEL256、ECB、Null文字でPAD */ $codeBook = new CodeBook(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB, CodeBook::PAD_NULL); list($encrypted) = $codeBook->encrypt($key, $text); //暗号化(ECBはIV不要) $decrypted = $codeBook->decrypt($key, $encrypted); //復号 // => "秘密のメッセージ => (略) => 秘密のメッセージ" echo $text . ' => ' . $encrypted . ' => ' . $decrypted; echo '<br />'; echo var_dump($text === $decrypted); // => bool(true) echo '<hr />'; /* Blowfish、CBC、スペースでPAD */ $codeBook = new CodeBook(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC, CodeBook::PAD_SPACE); list($encrypted, $iv) = $codeBook->encrypt($key, $text); //暗号化 $decrypted = $codeBook->decrypt($key, $encrypted, $iv); //復号 // => "秘密のメッセージ => (略) => 秘密のメッセージ" echo $text . ' => ' . $encrypted . ' => ' . $decrypted; echo '<br />'; echo var_dump($text === $decrypted); // => bool(true)
Output for git.master, git.master_jit, rfc.property-hooks
Fatal error: Uncaught Error: Undefined constant "MCRYPT_RIJNDAEL_128" in /in/W0dRc:23 Stack trace: #0 /in/W0dRc(150): CodeBook->__construct() #1 {main} thrown in /in/W0dRc on line 23
Process exited with code 255.

This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.

Active branches

Archived branches

Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page


preferences:
40.7 ms | 401 KiB | 8 Q