AES加解密功能故障求助:PHP+JS实现无法正常解密
问题分析与解决方案
你的核心问题是加密时没有将生成的IV与密文一起传递给解密端,且错误地从Base64编码后的密文中截取IV(Base64编码后的字符长度和原始二进制IV长度不匹配,截取的内容并非真正的IV)。另外还有几个次要问题:加密接口返回了调试输出,干扰了密文的正常获取;AES-256要求密钥长度为32字节,当前密钥长度不足,openssl会自动补全但存在安全隐患。
修正后的代码实现
1. index.html(无需修改)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Chiffrement AES</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="container"> <h2>Chiffrement AES</h2> <textarea id="message" placeholder="Entrez votre message"></textarea> <button onclick="encryptMessage()">Crypter</button> <div id="encryptedMessage"></div> </div> <textarea id="encryptedText" placeholder="Entrez le message crypté"></textarea> <button onclick="decryptMessage()">Décrypter</button> <div id="decryptedMessage"></div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="script.js"></script> </body> </html>
2. script.js(调整数据处理逻辑)
function encryptMessage() { var message = $('#message').val(); $.post("encrypt.php", { message: message }, function(data) { const result = JSON.parse(data); $('#encryptedMessage').text("Message crypté : " + result.encrypted_data); }); } function decryptMessage() { var encryptedText = $('#encryptedText').val(); $.post("decrypt.php", { encryptedText: encryptedText }, function(data) { const result = JSON.parse(data); if (result.success) { $('#decryptedMessage').text("Message décrypté : " + result.decrypted_data); } else { $('#decryptedMessage').text("Erreur de décryptage : " + result.error); } }); }
3. encrypt.php(修复IV传递与密钥问题)
<?php header('Content-Type: application/json'); if ($_SERVER["REQUEST_METHOD"] == "POST") { $message = $_POST['message']; // 将短密钥转换为AES-256要求的32字节二进制密钥 $secretKey = hash('sha256', 'CleSecrete', true); $cipher = "aes-256-cbc"; $ivlen = openssl_cipher_iv_length($cipher); $iv = openssl_random_pseudo_bytes($ivlen); // 获取二进制密文,将IV与密文拼接后Base64编码 $encrypted_raw = openssl_encrypt($message, $cipher, $secretKey, OPENSSL_RAW_DATA, $iv); $encrypted_data = base64_encode($iv . '::' . $encrypted_raw); echo json_encode([ 'encrypted_data' => $encrypted_data ]); } ?>
4. decrypt.php(修复IV获取逻辑)
<?php header('Content-Type: application/json'); if ($_SERVER["REQUEST_METHOD"] == "POST") { $encryptedText = $_POST['encryptedText']; $secretKey = hash('sha256', 'CleSecrete', true); $cipher = "aes-256-cbc"; // 解码Base64并拆分IV与密文 $decoded_data = base64_decode($encryptedText); list($iv, $encrypted_raw) = explode('::', $decoded_data, 2); $ivlen = openssl_cipher_iv_length($cipher); if (strlen($iv) !== $ivlen) { echo json_encode([ 'success' => false, 'error' => 'Longueur d\'IV invalide' ]); exit; } // 解密操作 $decrypted = openssl_decrypt($encrypted_raw, $cipher, $secretKey, OPENSSL_RAW_DATA, $iv); if ($decrypted === false) { $errors = []; while ($msg = openssl_error_string()) { $errors[] = $msg; } echo json_encode([ 'success' => false, 'error' => implode('<br>', $errors) ]); } else { echo json_encode([ 'success' => true, 'decrypted_data' => $decrypted ]); } } ?>
关键修改说明
- IV的正确传递:加密时将二进制IV和二进制密文用分隔符拼接后再Base64编码,解密时先解码再拆分,确保解密使用的IV与加密时完全一致。
- 密钥规范:通过SHA-256哈希将短密钥转换为32字节二进制密钥,符合AES-256的长度要求。
- 数据格式标准化:使用JSON格式返回数据,避免调试输出干扰前端获取有效密文,同时让错误处理更清晰。
- 参数优化:使用
OPENSSL_RAW_DATA获取二进制密文,减少不必要的编码转换,提升处理效率。
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

