如何在Flutter应用中安全保护API调用并隐藏请求敏感信息?
在Flutter中防止API请求被抓包的解决方案
HttpToolKit这类工具能抓取请求信息,本质是通过代理劫持并解密HTTPS流量,或是直接读取未加密的HTTP请求。以下是针对性的解决办法:
1. 检测并阻止代理请求
直接检查应用是否通过代理网络访问,一旦检测到代理就终止请求,避免流量被劫持。
通过dart:io的HttpClient实现代理检测:
import 'dart:io'; import 'package:http/http.dart' as http; Future<bool> isUsingProxy() async { final client = HttpClient(); try { // 替换为你的API域名 final proxyConfig = await client.findProxy('https://your-api-domain.com'); return !proxyConfig.startsWith('DIRECT'); } finally { client.close(); } } // 发起请求前执行检查 void sendRequest() async { if (await isUsingProxy()) { throw Exception('禁止使用代理访问,请关闭代理后重试'); } // 正常发起请求 final response = await http.get(Uri.parse('https://your-api-domain.com/data')); }
2. 配置HTTPS证书锁定(Certificate Pinning)
证书锁定会让应用仅信任指定的服务器SSL证书,即使抓包工具安装了根证书,也无法解密HTTPS流量。
针对http包,通过自定义HttpClient实现证书锁定:
import 'dart:io'; import 'package:http/http.dart' as http; Future<http.Client> getPinnedClient() async { final securityContext = SecurityContext(); // 读取提前存入assets的服务器证书(DER格式) final certBytes = await File('assets/certs/server-cert.cer').readAsBytes(); securityContext.setTrustedCertificatesBytes(certBytes); final httpClient = HttpClient(context: securityContext); return http.IOClient(httpClient); } // 使用带证书锁定的客户端发起请求 void sendSecureRequest() async { final client = await getPinnedClient(); try { final response = await client.get(Uri.parse('https://your-api-domain.com/data')); } finally { client.close(); } }
注意:需将服务器证书转为DER格式,放入assets目录并在pubspec.yaml中声明资源路径。
3. 加密敏感请求内容
对请求中的敏感数据(如token、用户信息、请求体)进行加密,即使被抓包,工具也只能获取密文。
示例:用AES加密请求体(需引入encrypt包)
import 'package:encrypt/encrypt.dart'; import 'package:http/http.dart' as http; class EncryptHelper { // 需与后端约定32位密钥和16位向量 static final key = Key.fromUtf8('your-32-char-secret-key-here'); static final iv = IV.fromUtf8('your-16-char-iv-here'); static String encryptContent(String plainText) { final encrypter = Encrypter(AES(key, mode: AESMode.cbc)); return encrypter.encrypt(plainText, iv: iv).base64; } } // 发起加密请求 void sendEncryptedRequest() async { final rawBody = '{"username":"user123","password":"xxx123"}'; final encryptedBody = EncryptHelper.encryptContent(rawBody); final response = await http.post( Uri.parse('https://your-api-domain.com/login'), body: {'encrypted_data': encryptedBody}, ); }
后端需实现对应的解密逻辑,才能解析原始请求内容。
4. 代码混淆与加固
开启Flutter代码混淆,防止攻击者通过反编译获取API地址、加密密钥等敏感信息:
在android/app/build.gradle中开启混淆:
android { buildTypes { release { minifyEnabled true useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
在proguard-rules.pro中添加Flutter专用混淆规则:
-keep class io.flutter.app.** { *; } -keep class io.flutter.plugin.** { *; } -keep class io.flutter.util.** { *; } -keep class io.flutter.view.** { *; } -keep class io.flutter.** { *; } -keep class io.flutter.plugins.** { *; }
内容的提问来源于stack exchange,提问作者Hossain72
相关产品推荐
相关产品推荐

