首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP AES-ECB 解密亂碼問題根因分析與正確實現

     編輯:PHP 相關知識

PHP AES-ECB 解密亂碼問題根因分析與正確實現

AES-ECB 模式解密時常見亂碼,主因是 PKCS#7 填充移除邏輯錯誤。本文還原問題現場,給出正確解密實現。

問題重現

明文: abcd
KEY: 1234567890123456
加密後 Base64: T7UT2NQ1AFvR9unjA0wKWA==

錯誤實現(補位邏輯有誤):

<?php
function apiDataDecrypt($data, $key='') {
    $data = base64_decode($data);
    $pad = 16 - (strlen($data) % 16);
    $padData = $data . str_repeat(chr($pad), $pad); // 錯誤:解密不需補位
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $padData, MCRYPT_MODE_ECB);
}
?>

正確解密實現

<?php
function decryptString($str, $key) {
    $str = base64_decode($str);
    // 直接解密,mcrypt 自動處理填充
    $str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
    
    // 正確移除 PKCS#7 填充
    $block = mcrypt_get_block_size('rijndael_128', 'ecb');
    $pad = ord($str[strlen($str) - 1]);
    return substr($str, 0, strlen($str) - $pad);
}

$key = '1234567890123456';
$content = 'T7UT2NQ1AFvR9unjA0wKWA==';
echo decryptString($content, $key); // 輸出: abcd
?>

核心要點解析

  1. 解密不需手動補位:加密時由庫自動填充,解密後只需移除填充位元組。
  2. PKCS#7 填充規則:最後一位元組值 = 填充位元組數(1-16)。
  3. mcrypt 已棄用 (PHP 7.1+):新專案請改用 OpenSSL 或 Sodium:

現代 OpenSSL 實現 (推薦)

<?php
function aesDecrypt($data, $key) {
    $data = base64_decode($data);
    // OPENSSL_RAW_DATA 返回原始二進制,OPENSSL_ZERO_PADDING 手動處理填充
    $decrypted = openssl_decrypt($data, 'AES-128-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
    // 移除 PKCS#7
    $pad = ord($decrypted[strlen($decrypted) - 1]);
    return substr($decrypted, 0, -$pad);
}
?>

安全提醒

  • ECB 模式不安全(相同明文塊產生相同密文塊),生產環境請使用 CBC/GCM 模式 並配合隨機 IV。
  • 金鑰管理請使用 KMS 或環境變數,勿硬編碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved