Skip to content

Instantly share code, notes, and snippets.

@comuttun
Last active November 10, 2022 07:51
Show Gist options
  • Save comuttun/8347313 to your computer and use it in GitHub Desktop.
Save comuttun/8347313 to your computer and use it in GitHub Desktop.
PHP Encrypt Sample with CodeBook.php
<?php
/**
* CodeBook.php
* @version 0.2.1
* @see http://0-oo.net/sbox/php-tool-box/code-book
* @copyright 2009-2011 [email protected]
* @license http://0-oo.net/pryn/MIT_license.txt (The MIT license)
*/
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);
}
}
<?php
require 'CodeBook.php';
$key = '42a6c4a94d9fc42357f24362d1420f54';
$codebook = new CodeBook();
for ($i = 0; $i < 100; $i++) {
// AES(RIJNDAEL128), CBC, Padding with PKCS#5
list($encrypted, $iv) = $codebook->encrypt($key, 'hogehoge');
$iv_and_encrypted = "$iv##$encrypted";
echo "iv_and_encrypted=$iv_and_encrypted\n";
if (preg_match('/^(.+?)##(.+)$/', $iv_and_encrypted, $matches)) {
$matched_iv = $matches[1];
$matched_encrypted = $matches[2];
$decrypted = $codebook->decrypt($key, $matched_encrypted, $matched_iv);
echo "iv=$matched_iv, encrypted=$matched_encrypted, decrypted=$decrypted\n";
} else {
echo "encrypted data format error";
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment