You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
        ]);
    }
}
?>

关键修改说明

  1. IV的正确传递:加密时将二进制IV和二进制密文用分隔符拼接后再Base64编码,解密时先解码再拆分,确保解密使用的IV与加密时完全一致。
  2. 密钥规范:通过SHA-256哈希将短密钥转换为32字节二进制密钥,符合AES-256的长度要求。
  3. 数据格式标准化:使用JSON格式返回数据,避免调试输出干扰前端获取有效密文,同时让错误处理更清晰。
  4. 参数优化:使用OPENSSL_RAW_DATA获取二进制密文,减少不必要的编码转换,提升处理效率。

内容的提问来源于stack exchange,提问作者mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:28:11