android NTP鉴权

来源:互联网 发布:女王升级数据2017 编辑:程序博客网 时间:2024/06/05 00:37

1、NTP如何同步时间

NTP协议是对网络内所有具有时钟的设备进行时钟同步,使网络内所有设备的时钟保持一致。

系统时钟同步的工作过程如下:

Device A发送一个NTP报文给Device B,该报文带有它离开Device A时的时间戳,该时间戳为10:00:00am(T1)。

当此NTP报文到达Device B时,Device B加上自己的时间戳,该时间戳为11:00:01am(T2)。

当此NTP报文离开Device B时,Device B再加上自己的时间戳,该时间戳为11:00:02am(T3)。

当Device A接收到该响应报文时,Device A的本地时间为10:00:03am(T4)。

至此,Device A已经拥有足够的信息来计算两个重要的参数:

NTP报文的往返时延Delay=(T4-T1)-(T3-T2)=2秒。

Device A相对Device B的时间差offset=((T2-T1)+(T3-T4))/2=1小时。

这样,Device A就能够根据这些信息来设定自己的时钟,使之与Device B的时钟同步。
对于android平台,framework中有关于NTP客户端实现的代码SntpClient,使用其requestTime函数,即可同步时间。

2、鉴权模式修改

问题是这样的,最近有需求需要使用特定的NTP服务器,其服务器进行了鉴权加密处理,我使用Android原生的流程去进行时间同步,却一直请求超时,而使用Linux的ntpdate可以正确同步到时间。
下面是NTP报文格式:
这里写图片描述
其中最后两个字段,则是用于认证用的,分别是KEY ID和信息认证码。所以对于Android原生代码,则需要实现NTP V4版本的才能支持鉴权。从包的格式来看,需要多发KEY ID和信息认证码即可。

修改也不难,首先会从服务器端得到鉴权的KEY ID和鉴权信息。代码部分只需要将android里的NTP版本号改为4,在原本的包后加发一个KEY ID的4个字节数据,最后加发鉴权信息和包数据一起加密出来16个字节(MD5等,这个也得从服务器端得知)。

这样就试了一下,可以从服务器端同步到时间了,具体代码就不贴了,流程基本就是这样。

3、偶发同步到错误时间

但是后面发现一个bug,在同步的时候,会有概率(大概1/10)同步到错误的时间,看了一下包,其中 Originate Timestamp(NTP请求报文离开发送端时发送端的本地时间)和我请求时发出去的Transmit Timestamp(应答报文离开应答者时应答者的本地时间)不对应,这个时间就是我们在上面介绍的时间戳T1。但是Linux服务器使用ntpdate抓的包有时也这样,同步的时间是对的。。。

我对于SntpClient.java中的一处地方不是很理解,正常来说,这两处时间,应该是一样的才对,但是为什么SntpClient.java中不使用自己本地发出去的时间来计算,而是用了服务器返回的时间戳来计算?这里我不是很明白,希望有高手解答一下。

所以当我发现服务器返回的时间戳和我发出去的差别很大(针对我调试的这个服务器我觉得超过30分钟就是服务器回错了,当然这种方法很挫),我就直接用我自己发出去的时间来计算。
这里写图片描述

这下子就没出现同步时间错误的情况了。

0 0
原创粉丝点击