粗略使用OpenSSL编写Apple Push工具

好久没有写过博客了, 自从上家公司裁员,加入新公司之后,每天忙的不可开交,需求不断,每天23点下班,感觉一天24小时都不够用。还好现在大忙的时候已经过去了,临近过年,也没有什么太大的需求了,于是有空就写下博客,记录一下自己做的事。

作为一名iOS程序员,推送方面的知识是不可能不接触到的,做推送方面的东西又不可能不调试,每次我都是使用NWPusher这个工具来做测试,用起来确实很方便,但是我却不知道到底这个工具是怎么做出来的,我也很想知道,于是看了一波这个工具的代码,熟悉了基本流程之后,就自己尝试着做一个出来。虽然很拙劣,但毕竟也成功的将数据推了过来,主要分为以下几个步骤:

1. 准备工作

iOS推送,首先是要有配置证书,应该先前往
苹果开发者中心
去配置推送证书,如下图所示:
配置推送证书
点击"Create Certificate",创建推送证书,完成之后,下载证书并导入到KeyChain,最终在KeyChain里的效果如下所示:
推送证书
其中必须包含证书和一个私钥,我将他导出为p12文件,设置密码,保存即可。

2.解析证书

导出了p12, 我就可以加载并解析证书了,我使用OpenSSL库的方法来解析,代码如下图所示:
加载解析证书
使用PKCS12_parse方法解析p12文件,得到一个X509的证书和一个EVP_PKEY的私钥和一个STACK_OF(X509)*的根证书,如果有根证书的话。然后我们拿到证书的SubjectName,因为苹果的推送证书都包含了"Apple Development IOS Push Services"(开发环境) 或 “Apple Production IOS Push Services”(生产环境),所以我们只需要匹配字符串,即可判断该证书是否为推送证书。

3.Socket连接

要发送推送,我们首先要连接到苹果的推送服务器,创建socket并建立连接,如下图:
建立socket连接
其中,苹果的推送服务器地址如下所示:
服务器

我们先使用gethostbyname方法,拿到苹果推送服务器的ip地址,然后连接到2195端口即可

4.建立SSL连接

由于苹果推送服务器使用的是SSL连接,所以我们还需要建立SSL连接,建立的过程如下所示:
建立SSL连接
创建一个SSL_Ctx上下文,使用解析出来的证书及私钥,并使用SSL_new建立一个新的ssl连接,并用SSL_set_fd设置已建立连接的套接字,再使用SSL_set_connect_state将ssl的状态设置为连接状态,最后使用SSL_do_handshake进行握手连接,握手返加1表示已成功建立SSL连接。

SSL连接建立成功之后,我们可以使用SSL_get_peer_certificate来拿到Apple端的证书,如下所示:
Apple证书
输出结果如下所示:
Apple Cert Subject

5.构建推送报文

Apple的推送服务有三种格式,如下图所示,图片根据NWPusher代码绘制,若有错误遗漏,请批评指正。
推送报文格式
从图上我们可以看到,推送报文一共有三种格式。

  • 第一种第一个字节为command字段,其值固定为0, 之后2个字节是DeviceToken字节长度,固定为32个字节,大端序。然后是DeviceToken, 接下来2个字节为push json的长度,也是大端序,最大为256,最后便是push的内容了。总长度为 37 + Payload_Length.
  • 第二种第一个字节为command字段,其值固定为1, 与第一种相比,多了8个字节,其中4个字节用做Thread Identifier 线程标识,另外4个字节用于表示push过期时间戳。总长度为 45 + Payload_Length.
  • 第三种最为复杂,第一个字节依然为command字段,其值固定为2, 与前两种相比较,多了一些字段,command字段之后的4个字节用于表示消息长度,即除去command字段和消息长度字段之外的报文总长度,之后即为DeviceToken, Payload Data, Thread Identifier, Expire Timestamp, Priority等字段,分别标识为1,2,3,4,5, 总长度为 58 + Payload_Length.

为了简单起见,我只封装了第一种报文格式,代码如下所示:
解析json
这里使用jsoncpp库来做为json的解析工具,如果解析成功,则说明输入的数据是合法的json数据,否则表示json数据有误。

deviceTokenHex

deviceToken为32字节的二进制数据,但是我们输入的是一个字符串,所以我们应该要把64位的字符串转换为32位的二进制数据。其实我这里只是做了简单的处理,并没有包括验证DeviceToken合法性,处理空格等其他字符等流程。

封装push报文
构建完成之后,即可以将数据包发送给Apple Push服务器,代码如下图所示:
SSLWrite
调用SSL_write写入数据即可,SSL_write返回值为写入的数据长度。我们这里不做结果验证,简单的认为SSL_write返回正确即认为push成功。

push完成之后,手机即可接收到推送信息,如果要推送多条数据的话,可以继续写入push信息,但不要每写入一条就断开连接再重新连接,如此反复多次,Apple Push服务器可能会禁止本机ip访问。写入结束之后再断开SSL连接,如下所示:
断开SSL连接

结束

其实写这样一个工具还是蛮简单的,总结起来就是连接-封装-发送-关闭这几个步骤而已,不过因为不懂SSL,所以实现这个功能也花了一点点时间。特此记录,以后有时候可以在此基础上再写一个更完整更健壮的推送测试工具出来。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值