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

Flutter加密URL查询参数并在PHP中解密的技术问题

解决方案:Flutter加密完整查询参数 + PHP解密解析

核心思路

不要拆分加密查询参数的各个片段(如&function=),而是将所有需要传递的业务参数打包成一个完整字符串(键值对或JSON格式),整体加密后仅在URL中传递iv和加密后的密文,确保?后无明文业务参数。


Flutter端修改代码

1. 统一加密函数

删除重复的encryptJob和encryptMessage,用单一函数处理所有字符串加密:

import 'dart:convert';
import 'package:encrypt/encrypt.dart';
import 'package:http/http.dart' as http;

// 假设key和iv已提前定义(需与PHP端完全一致)
final Key key = Key.fromBase64('你的密钥Base64字符串');
final IV iv = IV.fromBase64('你的IVBase64字符串');

String encryptString(String input) {
  final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
  final encrypted = encrypter.encrypt(input, iv: iv);
  return encrypted.base64;
}

2. 重构参数加密与请求逻辑

将所有业务参数打包后整体加密,URL仅传递iv和加密后的密文:

Future<void> fetchData() async {
  // 1. 打包所有业务参数(示例:传递function和多个job)
  // 方式1:键值对格式(适合简单参数)
  final paramsString = "function=getJobs&jobs=$job1,$job2,$job3,$job4";
  
  // 方式2:JSON格式(适合复杂/多结构参数,推荐)
  // final paramsMap = {
  //   'function': 'getJobs',
  //   'jobs': [job1, job2, job3, job4]
  // };
  // final paramsString = jsonEncode(paramsMap);

  // 2. 加密完整参数字符串
  final encryptedParams = encryptString(paramsString);

  // 3. URL编码iv和密文,避免特殊字符破坏URL结构
  final encodedIV = Uri.encodeComponent(iv.base64);
  final encodedEncryptedParams = Uri.encodeComponent(encryptedParams);

  // 4. 构建无明文业务参数的URL
  final webServiceUrl = 'http://localhost/get_encrypt_request.php?iv=$encodedIV&data=$encodedEncryptedParams';
  final url = Uri.parse(webServiceUrl);

  final response = await http.get(url);

  print('$url\n');
  print(response.body);

  setState(() {
    data = response.body;
  });

  if (response.statusCode == 200) {
    print('请求成功');
  } else {
    print('获取数据失败:${response.statusCode}');
  }
}

PHP端解密与解析代码

确保AES配置与Flutter完全一致(密钥长度、模式、填充方式),解密后解析参数:

<?php
// 与Flutter端一致的密钥(需解码为二进制)
$key = base64_decode('你的密钥Base64字符串');

// 接收URL参数并解码
$iv = isset($_GET['iv']) ? base64_decode(urldecode($_GET['iv'])) : '';
$encryptedData = isset($_GET['data']) ? urldecode($_GET['data']) : '';

if (empty($iv) || empty($encryptedData)) {
    echo json_encode(['error' => '参数缺失']);
    exit;
}

// 解密数据(注意AES-256-CBC对应256位密钥,128位则用AES-128-CBC)
$decrypted = openssl_decrypt(
    base64_decode($encryptedData),
    'AES-256-CBC',
    $key,
    OPENSSL_RAW_DATA,
    $iv
);

if ($decrypted === false) {
    echo json_encode(['error' => '解密失败', 'detail' => openssl_error_string()]);
    exit;
}

// 解析参数(对应Flutter端的打包方式)
// 方式1:解析键值对字符串
parse_str($decrypted, $params);

// 方式2:解析JSON字符串(如果Flutter用JSON打包)
// $params = json_decode($decrypted, true);
// if (json_last_error() !== JSON_ERROR_NONE) {
//     echo json_encode(['error' => '参数解析失败']);
//     exit;
// }

// 业务逻辑处理
$function = $params['function'] ?? '';
$jobs = explode(',', $params['jobs'] ?? '');

if ($function === 'getJobs' && !empty($jobs)) {
    // 示例:根据jobs返回对应数据
    $result = [];
    foreach ($jobs as $job) {
        $result[] = [
            'job_id' => $job,
            'name' => '任务_' . $job,
            'status' => '执行中'
        ];
    }
    echo json_encode($result);
} else {
    echo json_encode(['error' => '无效业务参数']);
}
?>

关键注意事项

  1. 配置一致性:Flutter与PHP端必须使用相同的密钥、IV、AES模式(CBC)和填充方式(PKCS7,两端默认均为该填充)。
  2. URL编码:加密后的Base64字符串可能包含+、/、=等URL特殊字符,必须用Uri.encodeComponent(Flutter)和urldecode(PHP)处理,避免参数解析错误。
  3. 参数打包方式:简单参数用键值对,复杂结构推荐用JSON,提升扩展性和可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:05:08