谁动了我的SunEC?——记深夜排查SSL握手失败的惊魂一小时
文章首发公众号『风象南』
问题初现
某日下午,正在进行一个项目沟通会,团队A同学找到我
"昨天说的那个功能做好了,验证了下基本流程没问题,但是测试过程发现个问题,就是调用完我新加的那个方法后再次访问界面就失败了,服务端口、进程资源啥的都正常,我分析了下,暂时没找到问题,但是重启服务后再访问界面就没有问题。"
又说道:"新增的那个方法不是经常调用,也就配置初始化时候调一下,影响不大,这个问题要不要解决。"
我说:"那得解决呀,没找到问题原因你就不确定什么时候会再次发生,即使重启正常了,可能运行一会或者操作个啥就又出问题了,另外,万一这个问题影响的不止这一处不就是留了个大坑,你再去查查看,如果没解决我等会开完会一起看看"。
排查定位
然后我接着开会,随后又准备了一些项目材料、设计文档,忙完这些已经是晚上10:00了。
突然想起来中午A同学的那个问题,过去看了下A同学还在工位,我过去问了下
"找到问题了吗 ?"
A同学说:"还没有找到,他看了代码好像没什么问题,不知道是不是其他人提交的代码影响的。"
接着翻起了代码提交记录。
我说:"错误提示是什么,异常信息给我看下。"
A同学说:"服务端没有错误,就是前端界面访问提示错误。"
如下图
我看了下,有意思,我就喜欢这种一眼看上去错误提示很简单但没什么头绪的问题,关键错误就是这行
"ERR_SSL_PROTOCOL_ERROR"
,
大致表达的意思就是:错误的SSL协议
我问了下:"你新增的代码里有修改服务侧SSL的什么配置参数吗 ?"
A同学说:"没有。"
我说:"把SSL先关掉测试下。"
A同学关掉服务侧SSL,启动->调用他新增的方法->访问界面,没有问题
我说:"把SSL打开,在控制层注释调你新增的业务方法调用。"
A同学注释掉业务方法调用,启动->调用他新增的方法->访问界面,没有问题
我说:"这就排除了全局拦截、AOP之类的影响,那大概率就是你的方法里改了SSL的什么配置,导致前后端无法正常进行握手通信了。"
随后我同A同学又检查了一遍代码,确实没发现修改SSL相关配置的地方
我说:"Wireshake抓包看一下."
A同学抓完包,分析后确实是握手过程失败了。奇了个怪。
过程回顾
随后,我开始思考整个过程。
1、关掉SSL没事,那一定是调用过程动了SSL的参数或者依赖的什么组件
2、开启SSL,注释调业务方法调用也没问题,说明全局拦截器、自定义的AOP逻辑里面也没有问题
3、抓包结果,前端提交的算法套件参数没有变化,服务端没有正常返回,说明肯定还是服务端的问题
4、那既然是服务端的问题,而且只发生在调用了新增的方法后,那问题肯定还是在整个新增的方法中
5、既然没有改SSL配置,有没有可能服务端的算法套件或者算法提供者被改变了,如果有使用过"Bouncy Castle" 这个库的同学应该知道,使用这个库需要添加一行代码
Security.addProvider(xxx)
而类似这种代码是可以修改Java运行中的密码算法提供者的,包括删除。
小样哪里走
我说:"加两个断点,1个在项目启动完看一下Provider列表,1个在调完新增的方法后在看一下Provider列表。"
A同学开始操作
项目启动完成通过通过调用方法Security.getProviders()
查看当前加载的Provider列表,可以看到列表中总共14个对象
调用新增的方法后,再次通过调用查看Provider列表的方法,此时,发现少了一个 SunEC。
那么大概率是因为SunEC被删除了导致的,大致确定了问题原因应该是删除了SunEC导致服务侧的算法提供者找不到了,无法正常提供SSL能力。当然,还需要验证。
而删除的Provider的关键代码就是
Security.removeProvider("SunEC")
随后,A同学进行代码全局搜索,没有发现这行代码的踪迹。
奇怪了,难道是引入的库里面删的 ?随后搜索范围加上了依赖的三方库。
果然,在一个公司封装的基础库的类里面找到了
而A同学刚好在他的逻辑过程中调用了该类的一个方法。
随后进行了验证,发现确实是这行代码带来的影响,然后将问题反馈到负责这个库的同事进行了调整。
至此,问题解决。
问题原因就是因为删除了JDK默认自带的SunEC Provider,由于HTTPS握手过程中服务侧依赖的算法提供者不能正常加载导致后续的算法套件、密码运算操作不能正常工作。
当然,仅通过文字还是无法完全呈现出问题分析定位的那种感觉与画面,珍惜每一次问题定位分析的过程,其中蕴含的思考、经验在未来都是你的知识资产与价值体现。
故事未完
看着A同学的背影
"一瞬间,又想起了曾经多少次为了解决一个问题,奋战到天亮的激情岁月。"
至今,激情未减,战斗仍在继续。。。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
数据同步写Oracle表耗时25分钟缩短到23秒——SeaTunnel性能优化
本文主要给大家介绍JDBC Source批处理任务动态切分优化,希望大家批评指正 JDBC Source 如果配置了table_path 和 partition_column,引擎会对数据进行动态切分,可以通过分析样本数据优化切分区间,规避数据倾斜问题。 目前发现任务即使配置了where_condition,动态切分算法仍然会把数据进行全表切分,在从大表中读取少量数据的场景下,任务切分阶段会耗费大量的时间,需要修改下面相关的流程进行优化。 下面所有出现SQL语句的地方均以MySQL为例子进行说明,具体不同的数据源有不同的子类方法overwrite实现。 数据切分主流程 数据动态切分的代码入口位于DynamicChunkSplitter类中的splitTableIntoChunks方法,流程图中标红的方框表示需要修改的部分,详细在下面的子流程中展开说明。 查询最大最小值 需要加上Source的where_condition配置的判断和拼接。 通用字段切分 查询数据总条数部分 (1)增加且where_condition配置为空才走"是"的分支 (2)修改"否"分支,增加where_cond...
- 下一篇
DeepSeek 开源周回顾「GitHub 热点速览」
上周,DeepSeek 发布的开源项目用一个词形容就是:**榨干性能!**由于篇幅有限,这里仅列出项目名称和简介,感兴趣的同学可以前往 DeepSeek 的开源组织页面,深入探索每个项目的精彩之处! 第一天 FlashMLA:基于 Hopper GPU 的高效 MLA 解码内核 第二天 DeepEP:专为 MoE 和 EP 设计的高效通信库 第三天 DeepGEMM:高效矩阵乘法(GEMM)库 第四天 DualPipe:双向流水线并行算法 EPLB:自动平衡 GPU 负载 profile-data:训练和推理框架的分析数据 第五天 3FS:高性能分布式文件系统 GitHub 地址:github.com/deepseek-ai 说回上周的热门开源项目,首当其冲的是用于构建实时音视频应用的 Python 库 FastRTC,它可以帮助开发者快速实现基于 AI 的语音助手、实时翻译和语音控制等应用。好久没发 Java Web 项目了,这次的 music-website 是用 Vue 和 Spring Boot 技术栈打造的音乐网站,非常适合想要学习这些技术的同学。如果你需要跨设备的推送通知服...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7设置SWAP分区,小内存服务器的救世主