一次IOS通知推送问题排查全过程

原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。

发现问题

在上周一个将要下班的夜晚,测试突然和我打招呼,说IOS推送的修复更新上线后存在问题,后台报错。

连忙跑到测试那里看报错详情,报错如下:

一次IOS通知推送问题排查全过程

重现问题

看到这个报错后,在网上搜索了一下,这种错误一般都是因为客户端不信任服务端SSL证书导致的,回想工作以来,好像遇到这种问题好多次了,只要将证书导入一下就好了。

由于不能冒然在线上修改解决问题,于是获取推送相关信息(如:设备token)后,到自己电脑上去测试,看是否能重现问题。

啪啦啪啦,代码修改完毕,点运行坐等错误出现。

5秒钟过后,发现推送消息发送成功了,没有出现报错,有点懵逼!心里想,代码都是完全一样的啊,怎么线上报错,我这却是好的呢???

纠结了一会,于是开始静下心来分析:

  1. 代码肯定是一样的,应该不是表面上的代码原因。
  2. 其次推送设备也是一样的,应该也不是手机问题。
  3. 那么。。。

就在没有头绪之际,我又扫了一眼工程目录,发现了jdk8,但我们线上系统使用的是jdk7啊。

一次IOS通知推送问题排查全过程

于是我将自己工程的jdk8换成jdk7试一下,同样的报错终于出现了!

那为什么jdk8没问题,jdk7却报错呢???

寻找原因

围绕着网上的说法和之前的经验,这 hand_failure错误应该是SSL/TLS握手过程中不信任服务端证书导致的,那办法很简单,去苹果官网找到苹果服务端提供的证书,导入到java的证书信任库cacert文件中即可。

一次IOS通知推送问题排查全过程

于是,下载了证书文件 GeoTrust_Global__CA.cer,并用jdk自带的keytool工具将证书导入到cacert文件中,如下:

一次IOS通知推送问题排查全过程
如上,导入过程中,发现提示已经有这个证书了,当时没想那么多,再导一次试试吧!

导入后,再次运行代码,结果还是报错!

心里又慌乱起来,没招了,于是又百度/google去了,但搜索出来的结论几乎都是证书信任问题,和自己的招式一样!

一次IOS通知推送问题排查全过程

同时,也了解了一下SSL/TLS协议相关知识,大致握手过程如下:

一次IOS通知推送问题排查全过程

详细如下:

  1. 客户端发送 clientHello消息,告诉服务端我使用的 TLS版本与加密套件等。
  2. 服务器返回 serverHello消息,告诉自己选择哪个 TLS协议版本与加密套件等。
  3. 服务器发送 Certification消息,将自己的 数字证书(包括服务器名称、CA和公钥)作为消息内容发给客户端。
  4. 客户端 Certificate verify校验服务器的 数字证书的有效性。
  5. 客户端 Change cipher spec选择加密套件并生成 会话密钥(客户端与服务器之间后续的数据传输将使用此会话密钥)。
  6. 客户端、服务器之间发送加密数据。

另外,jvm有一个 -Djavax.net.debug=SSL的参数,可以把SSL/TLS的握手过程都在控制台通过日志显示出来,如下:

一次IOS通知推送问题排查全过程

Ok,既然知道了握手过程,那就把SSL/TLS的日志显示出来看一下吧,看看是什么阶段出现的问题,如下:

一次IOS通知推送问题排查全过程
这说明 GeoTrust_Global.cer证书确实已经添加到信任库中了,而详细的SSL日志如下:

一次IOS通知推送问题排查全过程

如上图,报错发生在clientHello发送之后,在读服务端返回的serverHello消息时,却读到的是 Alert:handshake_failure警告信息,然后SSL握手就中断了,就好像你在和服务器打招呼,然后服务器回复了一个滚蛋一样!

百思不得其解?

准备放弃

一会,我看到测试走了过来。

测试:”问题解决的怎么样了,啥情况啊”

:”还不知道,本来以为很简单,实际上并没有,jdk8可以,7不行”

测试:”好吧”

:”要不升级jdk8吧”

测试:”能行吗”

:”……能行,jdk兼容性都很好,而且其它系统都已经升级过了,这个系统本来也计划要升,问题不大”

测试:”……好的”

于是,测试去升级jdk8了,本来我应该站在测试身后等待问题被解决,但我还是想在这期间查一查根本原因,于是又琢磨了起来。

发现真相

回想起,这个系统以前本来是jdk6,就是因为苹果强制开发者必须使用Https,且需要TLSv1.2版本,而jdk7才开始支持TLSv1.2,所以这个系统才升级到jdk7,那现在这个报错会不会…

于是,我赶紧使用TLSv1.2试试,添加jvm参数 -Dhttps.protocols=TLSv1.2即可强制https使用TLSv1.2版本协议,如下:

一次IOS通知推送问题排查全过程

加完后再次运行,报错依旧,那还有那里可能会有问题呢?

我突然灵光一闪,使用jdk7运行一次,再使用jdk8运行一次,将两次的SSL日志对比一下,看看哪里不一样,说不定能找到线索!

于是我马上试运行并对比两次SSL日志,发现两次SSL日志中TLS协议使用的加密套件不同,如下图:

jdk7的调试信息如下 :

一次IOS通知推送问题排查全过程
jdk8的调试信息如下:
一次IOS通知推送问题排查全过程
jdk8的TLS握手在服务端ServerHello之后,选择的加密套件是 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,而jdk7中可供选择的加密套件中没有 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

问题差不多清晰了,应该是jdk7中的加密套件,苹果服务器觉得太老不安全,都不支持了,那么如果我使用jdk8,并将加密套件强制为jdk7中的加密套件呢,应该也是会报错的!

于是,我还是使用jdk8,并添加了jvm参数 -Dhttps.cipherSuites=SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA,SSL_RSA_WITH_RC4_128_MD5,SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,以强制jdk8使用jdk7的加密套件,如下:

一次IOS通知推送问题排查全过程

再次运行后,果然报错了!所以应该是jdk8支持了一些新的加密套件,而苹果服务端只认这些新的加密套件导致的。

于是,我去jdk官网,查了一下jdk8的新增特性,发现 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384中AES加密算法的GCM模式在jdk8中才支持,如下:

一次IOS通知推送问题排查全过程

至此,问题原因全部搞清楚了,测试升级jdk8后也报告推送正常,此时已是10点多,两人写写日报赶紧回家去了……

往期内容

密码学入门
时区的坑,不想再踩了!
常见的Socket网络异常场景分析
字符编码解惑

Original: https://www.cnblogs.com/codelogs/p/16221107.html
Author: 扣钉日记
Title: 一次IOS通知推送问题排查全过程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/715265/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 两点之间直线最短,你写的是代码,我写的是艺术

    随着需求迭代,团队代码量逐渐增多,熵增崭露头角。临近月底,我打开部分程序,再做一次代码走查。 ✅ 两点之间直线最短 我在做代码走查的时候,发现一个service方法里有这么一段代码…

    技术杂谈 2023年7月11日
    080
  • 文件的压缩与打包

    文件的压缩与打包 常用文件拓展名 *.tar.gz tar程序打包的文件,并且经过gzip的压缩 *.tar.bz2 tar程序打包的文件,并且经过bzip2的压缩 tar 命令,…

    技术杂谈 2023年7月11日
    065
  • 【软考】信息系统安全技术

    《信息安全等级保护管理办法》中5个等级的区别 对于公民、法人和其他组织的合法权益没有 特别严重损害的说法 作者:奔跑的金鱼 出处:https://www.cnblogs.com/O…

    技术杂谈 2023年5月31日
    095
  • Spark基本知识

    Spark基本知识 Spark 是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。 Hadoop Hadoop 是由 java 语言编写的,在分布式服务器集群上存储海量数据并…

    技术杂谈 2023年7月11日
    0102
  • IO复用三种方式

    IO复用技术,简单来说就是同时监听多个描述符。在没有用到IO复用以前,只能是一个线程或一个线程去监听,服务端同时有多个连接的时候,需要创建多个线程或者进程。而且,并不是所有的连接是…

    技术杂谈 2023年6月21日
    0107
  • 基于六轴传感器MPU6050的物体移动监测报警系统

    一 系统简介 1.简介 MPU-60×0 是全球首例 9 轴运动处理传感器。它集成了 3 轴MEMS陀螺仪,3 轴MEMS加速度计,以及一个可扩展的数字运动处理器 DMP…

    技术杂谈 2023年5月31日
    097
  • 【数据结构】11.java源码关于TreeMap

    目录 1.TreehMap的内部结构2.TreehMap构造函数3.元素新增策略4.元素删除5.元素修改和查找6.特殊操作7.扩容8.总结 1.TreeMap的内部结构 首先确认一…

    技术杂谈 2023年7月24日
    097
  • 一文搞懂│什么是跨域?如何解决跨域?

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    技术杂谈 2023年7月11日
    063
  • 支持JDK19虚拟线程的web框架,之一:体验

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于虚拟线程 随着JDK19 GA…

    技术杂谈 2023年7月11日
    086
  • 开发,从未如此清晰

    关于开发,我们已经有了太多的方法论和工具,这之间其实很难说哪个方法论是正确的,哪个工具是最好用的;其实开发是”任性的”,它没有定律,如人饮水冷暖自知,其过程…

    技术杂谈 2023年5月31日
    0111
  • Jedis操作hash和Jedis操作List

    Jedis操作hash和Jedis操作List 哈希类型 hash :map个时间哦 hset hget hgetAll package com.ailyt.jiedis.test…

    技术杂谈 2023年6月21日
    0109
  • 【Python编程】使用jupyternotebook学习python并快速发布CSDN博客

    推荐:jupyter notebook+CSDN博客搭配学习模式 该模式分为两步: 使用jupyter notebook编写学习文件(.ipynb格式),如下图所示: 例如撰写第一…

    技术杂谈 2023年7月24日
    073
  • 读经典【1】重构:改善既有代码的设计

    五星好评。很实用。 最近读了重构原版书,同时也在使用其中的一些技巧来改善工作中的项目,自己改完代码会有成就感。 这本书改变了我原有的思想钢印:代码能成功跑起来就不要去动它。实际上,…

    技术杂谈 2023年7月25日
    084
  • 古传拳经拳法秘要

    《古传拳经拳法秘要》(手抄本) 国术馆 2022-05-05 18:33 更多珍贵拳谱资料 关注公众号”老拳谱” 勿使前辈之遗珍失于我手 点击图片了解与报名…

    技术杂谈 2023年5月31日
    075
  • 故障排查:是什么 导致了服务器端口telnet失败?

    telnet命令的主要作用是与目标端口进行TCP连接(即完成TCP三次握手)。 当服务端启动后,但是telnet其监听的端口,却失败了。或者,当服务端运行了一段时间后,突然其监听的…

    技术杂谈 2023年6月1日
    0115
  • 浅析渗透测试之手动和自动的优缺点

    手动渗透测试和自动渗透测试本是出于相同的目的,即帮助企业主动发现漏洞,了解现有安全措施的成效或不足。它们之间的唯一区别就是执行方式不同,手动渗透测试是由人工来完成,自动渗透测试是由…

    技术杂谈 2023年5月31日
    095
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球