当前位置: 首页 > news >正文

Flutter 自签名证书

前言
Flutter项目中服务器使用了自签名证书,如果直接使用https请求或者wss请求的话会报证书签名错误。

HandshakeException: Handshake error in client (OS Error:
I/flutter (28959): │ 💡 CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate(handshake.cc:359))

或者

CERTIFICATE_VERIFY_FAILED: self signed certificate in certificate chain(handshake.cc:354))
信任自签名证书
1.忽略证书校验
你可以通过以下步骤忽略证书验证。从而接受自签名证书

首先创建一个class 重写HttpOverrides

class MyHttpOverrides extends HttpOverrides {HttpClient createHttpClient(SecurityContext context) {return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) {//add your certificate verification logic herereturn true;};}
}

然后在main 方法将MyHttpOverrides 设置成全局的HttpOverrides。

HttpOverrides.global = new DevHttpOverrides();
当系统检测证书有问题时,会通过回调badCertificateCallback让我们有机会接受或拒绝这个错误的证书,当返回true时,表示我们接受这个证书,会继续完成通讯请求,当返回false时,表示我们不接受错误的证书,https通讯将失败。

当然你也可以在badCertificateCallback添加自己的证书校验逻辑。强烈不建议在正式环境将badCertificateCallback直接返回true,因为这样会接受所有的证书,相当于SSL加密层形同虚设,很容易造成中间人攻击。

2.使用本地CA根证书验证服务器证书
我们可以将服务器用来生成自签名证书的CA证书放在本地,设置为受信任的证书,然后用这个证书校验服务器证书。代码如下:

class MyHttpOverrides extends HttpOverrides {HttpClient createHttpClient(SecurityContext context) {//加载本地根证书ByteData data = await rootBundle.load('assets/data/ca-cert.pem');final SecurityContext clientContext = SecurityContext()//使用此方法设置受信任根证书..setTrustedCertificatesBytes(data.buffer.asUint8List())return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) {//add your certificate verification logic herereturn false;};}
}

这种方式能极大提高安全性。

常见问题
CERTIFICATE_VERIFY_FAILED: Hostname mismatch

Flutter ssl默认会检测证书 subject 中的CN字段和请求url 中的host 是否一致。 如果不一致会报这个错误。

如果请求的url时https://baidu.com/tanslate , 那么服务器的证书CN字段必须包含Baidu.com。

很可惜目前基于flutter3.0 没有提供相应的API 去忽略hostname 检测,我们能做的就是在badCertificateCallback 添加自己的校验逻辑,如下:

  ..badCertificateCallback = (X509Certificate cert, String host, int port) {if(host=="baidu.com")return true;else return false;};

2.本地CA根证书验证服务器证书时,当服务器证书的签名不对时,会回调到badCertificateCallback, 而其他证书错误也会回调到badCertificateCallback, 如果要如何区分不同的证书错误原因,则需要手动去校验证书的签名等信息。

class MyHttpOverrides extends HttpOverrides {MyHttpOverrides() {}HttpClient createHttpClient(SecurityContext? context) {ByteData data = await rootBundle.load('assets/data/ca-cert.pem');final SecurityContext clientContext = SecurityContext()..setTrustedCertificatesBytes(caCertificate);return super.createHttpClient(clientContext)..badCertificateCallback = (X509Certificate cert, String host, int port) //根据根证书校验服务器证书bool isverify = verifyCertificate(ca_cert, cert.pem);if (!isverify){//签名错误return false;}if (currentIp != host) {return false;} else {return true;}};}
}

其中verifyCertificate 方法如下,用到了x509这个package。传送门

import 'dart:convert';
import 'dart:typed_data';
import 'package:x509b/x509.dart' as x509;
import 'package:asn1lib/asn1lib.dart';import 'flutter_log.dart';bool verifyCertificate(String caCert, String serverCert) {// var strX1PublicKeyInfo = "-----BEGIN CERTIFICATE-----\nSOME PUBLIC KEY\n-----END CERTIFICATE-----";// var strX2Certificate = "-----BEGIN CERTIFICATE-----\nSOME CERTIFICATE\n-----END CERTIFICATE-----";var x1PublicKey = (x509.parsePem(caCert).single as x509.X509Certificate).publicKey as x509.RsaPublicKey;var x2Certificate = x509.parsePem(serverCert).single as x509.X509Certificate;var x2CertificateDER = decodePEM(serverCert);var asn1Parser = ASN1Parser(x2CertificateDER);var seq = asn1Parser.nextObject() as ASN1Sequence;var tbsSequence = seq.elements[0] as ASN1Sequence;var signature = x509.Signature(Uint8List.fromList(x2Certificate.signatureValue!));var verifier = x1PublicKey.createVerifier(x509.algorithms.signing.rsa.sha256);return verifier.verify(tbsSequence.encodedBytes, signature);
}Uint8List decodePEM(String pem) {var startsWith = ['-----BEGIN PUBLIC KEY-----','-----BEGIN PRIVATE KEY-----','-----BEGIN CERTIFICATE-----',];var endsWith = ['-----END PUBLIC KEY-----','-----END PRIVATE KEY-----','-----END CERTIFICATE-----'];pem=pem.trim();//HACKfor (var s in startsWith) {if (pem.startsWith(s)) pem = pem.substring(s.length);}for (var s in endsWith) {if (pem.trim().endsWith(s)) {Log().i("certificate:substring");pem = pem.trim().split(s)[0];}}//Dart base64 decoder does not support line breakspem = pem.replaceAll('\n', '');pem = pem.replaceAll('\r', '');return Uint8List.fromList(base64.decode(pem));
}

作者:星辰大海TT
链接:https://www.jianshu.com/p/5dfb882671a3

相关文章:

Flutter 自签名证书

前言 Flutter项目中服务器使用了自签名证书,如果直接使用https请求或者wss请求的话会报证书签名错误。 HandshakeException: Handshake error in client (OS Error: I/flutter (28959): │ 💡 CERTIFICATE_VERIFY_FAILED: unable to get local issuer c…...

观察者模式——解决解耦的钥匙

● 观察者模式介绍 观察者模式是一个使用频率非常高的模式,它最常用的地方是GUI系统、订阅——发布系统。因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得它们之间依赖性更小,甚至做到毫无依赖。以CUI系统来说&a…...

MATLAB和西门子SMART PLC UDP通信

MATLAB和SMART PLC的OPC通信请参考下面文章链接,这里不再赘述: MATLAB和西门子SMART PLC OPC通信-CSDN博客文章浏览阅读661次,点赞26次,收藏2次。西门子S7-200SMART PLC OPC软件的下载和使用,请查看下面文章Smart 200PLC PC Access SMART OPC通信_基于pc access smart的o…...

打造高效运营底座,极智嘉一体化软件系统彰显科技威能

在仓储成本和物流需求日益增加的今天,创新且高效的物流机器人解决方案能够显著提升物流运营效率,降低物流成本,实现智能化、精益化、一体化的物流管理。全球仓储机器人引领者极智嘉(Geek)以「一套系统,天生全能」为准则&#xff0…...

sqlsugar查询数据库下的所有表,批量修改表名字

查询数据库中的所有表 using SqlSugar;namespace 批量修改数据库表名 {internal class Program{static void Main(string[] args){SqlSugarClient sqlSugarClient new SqlSugarClient(new ConnectionConfig(){ConnectionString "Data Source(localdb)\\MSSQLLocalDB;In…...

如何用 GPT-4 全模式(All Tools)帮你高效学习和工作?

「十项全能」的 ChatGPT ,用起来感受如何? 之前,作为 ChatGPT Plus 用户,如果你集齐下面这五个模式,就会成为别人羡慕的对象。 但现在,人们更加期盼的,是下面这个提示的出现: 这个提…...

Cesium 展示——移动拖拽实体

文章目录 需求分析需求 将移动实体的事件加入右键中 ,实现移动拖拽实体,实现对实体的拖拽 移动前 移动后 分析 当鼠标按下时获取该实体。用viewer.scene.pick 来进行获取实体,并锁定相机(需加判断如果不是实体不能锁定相机)// 左键按下事件leftDownAction(e)...

javaSE学习笔记-未完

目录 前言 一、java基础 1.1概述 1.java语言发展史 2.Java语言版本 3.Java语言平台 4.Java语言特点 5.Java语言跨平台原理-可移植性 6.JRE和JDK的概述 7.JDK的下载和安装 8.JDK安装路径下的目录解释 9.path环境变量的作用及配置方式 10.classpath环境变量的作用及…...

分享一下微信小程序里怎么创建会员卡功能

在当今的数字化时代,微信小程序已经成为一种广泛使用的应用模式,涵盖了各种行业。对于企业而言,拥有一个会员卡系统可以更好地管理客户,提高客户忠诚度,并促进消费。本文将探讨如何在微信小程序中创建会员卡功能&#…...

吴恩达《机器学习》5-6:向量化

在深度学习和数值计算中,效率和性能是至关重要的。一个有效的方法是使用向量化技术,它可以显著提高计算速度,减少代码的复杂性。接下来将介绍向量化的概念以及如何在不同编程语言和工具中应用它,包括 Octave、MATLAB、Python、Num…...

《面向对象软件工程》笔记——1-2章

“学习不仅是一种必要,而且是一种愉快的活动。” - 尼尔阿姆斯特朗 文章目录 第一章 面向对象软件工程的范畴历史方面经济方面维护方面现代软件维护观点交付后维护的重要性 需求、分析和设计方面团队开发方面没有计划,测试,文档阶段的原因面向…...

1400台光刻机,ASML突然大举倾销,外媒惊呼中国芯片进展太快了

就在各方还认为中国芯片在高端芯片方面难以突破的时候,ASML却突然公布了重大消息,累计向中国交付的光刻机已达到1400台,中国已成为ASML的最大市场,这样的消息无疑让外媒颇为震惊。 发生这些变化,在于中国芯片近期所取得…...

Leetcode—187.重复的DNA序列【中等】

2023每日刷题&#xff08;二十&#xff09; Leetcode—187.重复的DNA序列 实现代码 class Solution { public:const int L 10;vector<string> findRepeatedDnaSequences(string s) {unordered_map<string, int> str;vector<string> ans;int len s.size()…...

inno setup 运行时进行文件复制和替换

问题描述&#xff1a; 当我们采用 inno setup进行打包时&#xff0c;需要实现将安装包中的某个文件进行替换&#xff0c;而且我们知道在Winodws系统可以有xcopy和copy两个命令可以提供该功能&#xff1b;而xcopy命令进行文件复制时会有如下提示&#xff1a; 此时需要手动输入字…...

睿思BI已支持3D图形

从睿思BI旗舰版V5.3开始&#xff0c;系统支持如下3D图形&#xff1a; 3D地球 3D地图 飞线图 3D金字塔 睿思BI采用ThreeJS实现3D功能&#xff0c;用户也可以基于系统接口&#xff0c;采用ThreeJS在数据大屏中实现自己的3D图形。 系统演示地址&#xff1a;睿思BI旗舰版https://…...

ARCGIS---dem生成高程点

1添加DEM 2在ArcToolbox中点击“3D Analyst工具\转换\由栅格转出\栅格转多点”&#xff0c;调用栅格转多点工具。 3在显示的栅格转多点对话框内&#xff0c;输入栅格选择下载的dem数据&#xff0c;为了保证正常输出&#xff0c;输出要素类最好是默认&#xff0c;方法选择ZTOL…...

2034:D 类音频功率放大器的引脚排列

2034芯片是一款无滤波器5.2W单声道纯D类音频放大器。低EMI适合应用于便携式设备中。 2034芯片的引脚排列&#xff1a; 2034芯片管脚描述&#xff1a; 2034芯片具有关断功能&#xff0c;延长系统的待机时间。过热保护功能增强系统。POP声抑Z功能改进了系统的听觉感受&#xff0…...

计算机网络第4章-IPv4

IPv4数据报格式 IPv4数据报格式如下图所示 其中&#xff0c;有如下的关键字段需要特别注意&#xff1a; 版本&#xff08;号&#xff09;&#xff1a; 版本字段共4比特&#xff0c;规定了数据报的IP协议版本。通过查看版本号吗&#xff0c;路由器能确定如何解释IP数据报的剩…...

Transformer的最简洁pytorch实现

目录 前言 1. 数据预处理 2. 模型参数 3. Positional Encoding 4. Pad Mask 5. Subsequence Mask 6. ScaledDotProductAttention 7. MultiHeadAttention 8. FeedForward Networks 9. Encoder Layer 10. Encoder 11. Decoder Layer 12. Decoder 13. Transformer 1…...

【嵌入式开发学习】__u-boot和bootloader到底有什么区别?

目录 前言 一、Bootloader 二、uboot 1. 硬件管理 2. 能够完成镜像烧录&#xff08;刷机&#xff09; 3. uboot的“生命周期” 4. uboot要提供命令式shell界面 三、bootloader 与 uboot的区别 (*&#xffe3;︶&#xffe3;)创作不易&#xff01;期待你们的 点赞、收藏…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...