專案需與 Java 端對接,雙方約定使用 AES-256-CBC 模式、PKCS7 填充、固定 IV 向量。本文提供完整 PHP 類別實作,確保跨語言加解密互通。
<?php
class MCrypt {
private $hex_iv = '00000000000000000000000000000000'; // 16 bytes IV
private $key = 'U1MjU1M0FDOUZ.Qz'; // 原始金鑰
function __construct() {
// SHA-256 派生 32 bytes 金鑰
$this->key = hash('sha256', $this->key, true);
}
function encrypt($str) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad); // PKCS7 填充
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode($encrypted);
}
function decrypt($code) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$str = mdecrypt_generic($td, base64_decode($code));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $this->strippadding($str);
}
private function strippadding($string) {
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if (preg_match("/$slastc{" . $slast . "}/", $string)) {
return substr($string, 0, strlen($string) - $slast);
}
return false;
}
function hexToStr($hex) {
$string = '';
for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
$string .= chr(hexdec($hex[$i] . $hex[$i+1]));
}
return $string;
}
}
// 測試範例
$encryption = new MCrypt();
echo $encryption->encrypt('123456') . "<br/>";
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w==');
?>
| 參數 | 值 | 說明 |
|---|---|---|
| 演算法 | AES-256-CBC | Rijndael 128 位元區塊,256 位元金鑰 |
| IV 向量 | 16 bytes 全零 | 十六進位 `00000000000000000000000000000000` |
| 金鑰派生 | SHA-256 | 原始金鑰經 hash('sha256', key, true) 產生 32 bytes |
| 填充模式 | PKCS7 | 區塊大小 16 bytes,不足補齊 |
| 輸出編碼 | Base64 | 加密結果經 base64_encode 輸出 |
PHP 7.1+ 已棄用 `mcrypt` 擴充套件,建議改用 `openssl_encrypt`/`openssl_decrypt` 實作相同邏輯,確保長期維護性。