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

Angular 5与PHP使用CryptoJS加密后PHP解密返回null问题

解决Angular CryptoJS加密后PHP解密返回null的问题

我之前也碰到过一模一样的问题,折腾了好一会儿才找到原因,咱们一步步来排查解决:

核心问题分析

出现null解密结果,大概率是这几个原因导致的:

  • 前端直接传递了CryptoJS的加密对象,而非序列化后的字符串格式
  • 请求头设置错误,导致参数没有正常传递到后端
  • 后端没有先确认参数是否接收成功,且第三方解密库的逻辑和CryptoJS默认加密逻辑不匹配

修正后的前端Angular代码

ngOnInit() {
  let user = "am";
  let key = "pizza";
  // 关键:将加密对象转为字符串格式,否则后端无法解析
  let enc = crypto.AES.encrypt(user, key).toString(); 
  
  // 先测试本地解密是否正常,确保前端加密逻辑没问题
  let dec = crypto.AES.decrypt(enc, key);
  console.log("本地解密结果:", dec.toString(crypto.enc.Utf8));

  // 修正请求头:Access-Control-Allow-Origin是后端响应头,前端不需要设置
  const headerOptions = new HttpHeaders()
    .set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

  const params = new HttpParams().set('name', enc);
  
  this.http.post('http://aff.local/test.php', params, { headers: headerOptions }).subscribe(
    res => {
      console.log(res);
      alert(res)
    }, 
    error => {
      console.log(error);
    }
  )
}

修正后的PHP脚本

<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
header('Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS');
header('Access-Control-Allow-Headers: *');

error_reporting(E_ALL);
include('./cryptojs-aes.php');
ini_set('log_errors', 0);
ini_set('display_errors', 1);

// 先确认是否接收到参数,避免空指针问题
if (!isset($_POST['name'])) {
    echo json_encode(['error' => '参数name未传递']);
    exit;
}

$host = "localhost";
$db = "dentist";
$user = "root";
$pass = "root";

try {
    $conn = new PDO("mysql:host={$host};dbname={$db};", $user, $pass);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $conn->exec("SET CHARACTER SET utf8mb4");

    $enc = $_POST['name'];
    $key = "pizza";
    
    // 可以先打印加密值,确认和前端输出一致,排查参数传递问题
    // var_dump($enc); 
    $dec = cryptoJSAesDecrypt($key, $enc);
    
    if (empty($dec)) {
        echo json_encode(['error' => '解密失败,请检查密钥或加密格式']);
    } else {
        echo json_encode($dec);
    }
} catch(PDOException $e) {
    echo json_encode(['error' => '数据库连接失败:' . $e->getMessage()]);
}
?>

额外排查建议

  1. 验证参数传递:在PHP里用var_dump($_POST)查看是否接收到前端传递的加密字符串,确保没有被转义或截断
  2. 匹配加密逻辑:如果第三方cryptojs-aes.php库还是无法解密,可以替换成以下原生openssl实现(完全匹配CryptoJS默认加密逻辑):
function cryptoJSAesDecrypt($passphrase, $jsonString){
    $obj = json_decode(base64_decode($jsonString), true);
    $salt = hex2bin($obj["s"]);
    $iv = hex2bin($obj["iv"]);
    $ciphertext = base64_decode($obj["ct"]);
    
    $iterations = 999;
    $key = hash_pbkdf2("sha1", $passphrase, $salt, $iterations, 32, true);
    
    $decrypted = openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    return $decrypted;
}

CryptoJS默认会用字符串密钥生成MD5密钥、随机IV,并将加密结果打包成JSON后base64编码,上面的函数就是对应这个流程的解密逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:39:26