开发者社区> 开发者说> 正文

【物联网智能网关-18】多通道远程安全升级

简介: 随着物联网各种项目的大量实施,在运行维护过程中,其技术人员的交通住宿成本及人力成本的逐年增加,让设备的远程维护,远程升级功能变得越来越重要了。
+关注继续查看

一个典型的物联网系统,往往有上百个,甚至成千上万个联网节点,并且每个节点联网的方式可能不同,比如有Zigbee联网,有430/470M无线方式联网,有GPRS/3G无线模块联网,有RS485/CAN总线方式联网,有以太网TCP/IP方式联网等等。如此种种节点,如果需要进行程序更新,这是一个非常令人头疼的事。

另外,随着物联网各种项目的大量实施,在运行维护过程中,其技术人员的交通住宿成本及人力成本的逐年增加,让设备的远程维护,远程升级功能变得越来越重要了。

但是要实现远程升级,也不是一件容易的事,需要重点解决如下三方面的事情:第一就是安全,如何防止有恶意的人篡改和远程升级相关设备的程序;第二就是远程升级通信信道的问题,比如国内的GPRS和3G模块,由于被分配的IP地址不是公网地址,所以必须反连,也就是说模块要主动请求服务器进行远程升级,而不是常规程序升级的做法,直接访问设备对设备进行升级,另外就是各种通信接口的支持,比如Zigbee,430/470M无线信道,由于这类设备,每次传输的字节数有限,实现远程升级功能也要充分考虑到这一点。第三就是可靠升级,比如升级一半,设备突然掉电,如何确保设备不变砖。

基于.NET Micro Framework系统的物联网智能网关,分别采用如下技术来解决以上所提到的问题。

【安全问题】

.NET Micro Framework系统,在V4.1版本之前,一直提供了两种加解密方法,一种是非对称加密RSA和对称加密XTEA(这部分代码一直没有开源,提供各种ARM版本和X86的连接库),但是这个库其中的RSA有两个致命的问题,一个是其生成的公钥和私钥无法和Windows或其他平台的目前已有的方法提供的一致,互不通用。另外一个问题就是其X86版本和嵌入式版本,其加解密竟然无法实现互解(另外也发现嵌入式版本的RSA加密,无法对特定长度的明文进行加解密)。

4.2版本之后,封装了OpenSSL中的RSA、AES,DES等加密方法,但是对一些运行.NET MicroFramework系统比较小的嵌入式设备来说, 集成一个OpenSSL库有些太大了,大概增加400K字节大小,比一个.NET Micro Framework系统还要大,这是让人无法承受的。

后续重新自行调整和构建了RSA相关代码,算相对完美的解决了这个问题。(关于加解密的详情,后续有专门的文件进行介绍)。

远程升级的思路:

首先对要升级的文件进行SHA1哈希计算,拼装成标准签名文件后,用RSA的私钥对该数据进行加密–- 对升级文件进行签名。

考虑到嵌入式系统RAM空间有限,数据可以分批,分片写入到Flash区域中,等完全写入完毕后,直接在Flash上(非NandFlash,可以直接访问),用预先下载好的公钥进行签名验证。
【信道问题】

其实.NET Micro Framework系统也提供了官方的远程升级方案,甚至为了实现这个功能,新提供一个MicroBooter来配合完成远程升级。但是其通信信道是基于.NET Micro Framework调试口的,这就有一个很大的问题,比如GPRS/3G通信设备无法远程直接访问,Zigbee,430/470M无线模块,每次传输的数据有限,都无法被配置为调试通道。

我们的解决方案是,信道和具体的升级功能功能完全剥离,这样信道的问题,就简化成如何远程获取升级文件和签名的问题。针对这个问题,可实现的方案有很多种,也可以分为主动式和被动式升级。

【可靠升级】

我们采取的方案是,接收到的数据,先更新到一个系统Flash区,下载完毕后,用公钥进行签名验证,验证通过后(一是验证来源是否可靠,另外就是验证升级文件的完整性),才置相关标志位,然后让系统复位,复位后根据相关的标志,把相关数据转移到正常程序区,并加载运行。

从以上步骤中可以看出,如果远程升级过程没有完成,原来的程序还将继续保持,并不会被破坏。

 

升级流程示意图如下:
image.png
下面让我们详细介绍完整的远程升级流程:

创建公钥和私钥

在示例“数据加密解密”中,我们提供了一个和.NET Micro Framework相对应的Windows版本的数据加密解密程序(界面如下图所示)。其用到的加解密函数,都是.NET Framework的标准加密解密库。

考虑到存储空间,设备端(.NET Micro Framework系统)的二进制格式的密钥和上位机的二进制格式略有不同,实际要小一些,比如公钥的指数,一般都固定为0x1,0x0,0x1三个字节的数,所以就省略了。同理私钥也是做了这样的处理。

但是xml格式的都是一样的,底层也提供了一个接口函数,可以直接导入XML格式的密钥。
image.png
为了各自的方便,我们为对应的PC端程序(远程升级的发起方)提供的是XML格式的私钥,为设备端(被升级的一方)提供的是二进制格式的公钥。

分别用刚才提到的工具进行导出。

导出私钥的相关代码其实很简单,默认是1024位的Key,代码如下:

RSACryptoServiceProvider mskey = new RSACryptoServiceProvider();

    stringxmlKey = mskey.ToXmlString(true);

针对二进制格式的公钥,其实我们仅导出128字节的Modulus的数据:

  byte[] key = new byte[128];

    Array.Copy(Modulus,0, key, 0, 128);

公钥部署

采用最新版本的YFAccessFlash工具(V3.12.0以上),把导出的二进制格式的公钥部署到设备上(.NET Micro Framework系统)。
image.png
公钥提取及程序部署、校验

以下代码完成公钥的提取(需要引用YFSoft.Config库)

byte[] PublicKey = new byte[128];

    if (YFSoft.Config.Read("PublicKey",PublicKey, 0, 128) == 0)

{

    //…

}

分以下四步分别完成程序的部署和校验(需要引用YFSoft.RemoteUpgrade库)

第一步:清空系统部署区

RemoteUpgrade.Initialize(); 

第二步:向系统数据区写数据(可以分块写)

RemoteUpgrade.Write(0, peFile, 0, peFile.Length);

 

第三步:RSA+SHA1校验

bool IsVerifyOK = (RemoteUpgrade.Verify(peFile.Length,Signature, PublicKey)==0);

 

第四步:置标志位,系统重启

RemoteUpgrade.Finish();

   

升级文件及签名数据远程传输

以上几步,基本上流程一致,没有多少变化,但是这一步,变数比较大。从物理信道上来说,可以是以太网、Wifi、蓝牙、无线(430M/470M)、Zigbee、RS232/RS485串口通信、GPRS/3G等等。
即使同一个信道,采用的升级策略也不相同,比如可以是主动式,和被动式。所谓的主动式,就是远程可以直接对远程的模块进行升级,是相对即时的一种的方式。而被动式,是远程模块,每隔特定的时间间隔,主动去访问指定的服务器,根据获取的信息,判断是否该升级。比如国内通过GPRS/3G通道,也只能采用这种方式了。

我们提供的两个例子,一个是基于以太网TCP/IP通信,一个是基于串口通信,都是主动式的。不过例子中提供了一个YFSoft.WireProtocol源码类,和特定的信道,还有主动被动都没有关系,只需要实现相关的委托接口就可以完成远程升级文件的接收或发送。

要实现的三个接口分别是:

public delegate int TransmitBytesHandle(byte[] buffer, intoffset, int count);

    public delegate int ReceiveBytesHandle(byte[]buffer, int offset, intcount);

    public delegate int GetReceiveCountHandle(); 

第一个是发送数据用的,第二个是接收数据用的,第三个是获取接收缓冲区数据个数的。并且这个YFSoft.WireProtocol.cs文件,桌面.NET Framework和设备.NET Micro Framework完全一样的。

比如如果通信信道是串口,则这三个接口的实现代码如下:

private int TransmitBytesHandle(byte[] buffer, intoffset, int count)

     {

          port.Write(buffer, offset, count);

          return0;

     }

 private intReceiveBytesHandle(byte[] buffer, int offset, intcount)

     {

         returnport.Read(buffer, offset, count);

     }

     private int GetReceiveCountHandle()

     {

         returnport.BytesToRead;

     }      

如果是网口,则代码如下:

private int TransmitBytesHandle(byte[] buffer, intoffset, int count)

     {

          returnsocket.Send(buffer, offset, count, SocketFlags.None);

     }

     private int ReceiveBytesHandle(byte[]buffer, int offset, intcount)

    {

         returnsocket.Receive(buffer, offset, count, SocketFlags.None);

     }

    private int GetReceiveCountHandle()

     {

         returnsocket.Available;

     }

接下来,在设备端主程序中,只需要添加两句代码,就可以实现远程升级的服务端功能。

如果是串口,代码如下:

  //远程升级服务(基于串口)

    PortServerUpdatetsu = new PortServerUpdate("COM1",115200,true);

    tsu.Launch();

 

如果是网口,代码如下:

//远程升级服务(基于TCP)

    TcpServerUpdatetsu = new TcpServerUpdate(10189,true);

    tsu.Launch()

 

PC端的接口实现类似,但是远程数据有所不同,由于串口方式和网口方式基本一样,所以我们仅举以太网通信方式。

具体的升级代码如下:

   private void btnUpdate_Click(objectsender, EventArgs e)

    {

        if(txtFiles.Text != null &&txtFiles.Text.Length > 0)

        {

            txtInfo.Text = ">>> 提取以下文件的数据...\r\n";              

            varfiles = Directory.EnumerateFiles(txtFiles.Text,"*.pe");

            MemoryStreamms = new MemoryStream();

            foreach(string file infiles)

            {

                txtInfo.Text += ">>> "+file + "\r\n";

                FileStreamtfs = new FileStream(file,FileMode.Open, FileAccess.Read);

                byte[]buffer = new byte[tfs.Length];

                tfs.Read(buffer, 0,buffer.Length);

                tfs.Close();

                ms.Write(buffer, 0,buffer.Length);

            }

            txtInfo.Text += ">>> 提取并合成数据成功!\r\n";

 

            //创建签名文件

            stringxmlPrivateKey = "<RSAKeyValue><Modulus>vBjTkuBruYPSBE5y5T7hd4KEADy6UuBk1v+Es8BOvggOsfEGvxJNraDTCxTPaNhVkbaCFIavw8amXoIkFzjDw7fV3JVDflsqZ4qg23DOcWz/DvF+12sNcXTsHX7HELJYObZI1lo1kE2fFej1uuRzr7v9DgoFurgg9tGU9gD3dCU=</Modulus><Exponent>AQAB</Exponent><P>4NIKd4E+/0RRT58FZriPTWkfysy8c1Hl7CbeKet1m7KDsatwxNYm6u+oKltmG8UQ73pUfsEbBFpCo/UgL36osQ==</P><Q>1i73MFObZqHBvAhBP+uAbDa33k9yBqePDC0lKL5bqw4AhWzKb3EJd0OWUYf+LxZKnYbmbYNIMolDskcnbPjftQ==</Q><DP>2L7HJoWthY6I0blfDLRcO+ZgpzURbiCECVNDlqiRvySwwIandq174b5ho0xwuc8Yz7hhY76qXFzkqIt3lzKGUQ==</DP><DQ>lkj0F0vC8bu0dZyRNCmpvcSTNYEnMDYoMFIJDdKr/ZVglj5kuNdm3fFlqyWyHBYXGvtJ+jOw2AzqnFBDALqMNQ==</DQ><InverseQ>jQhrgi6tUQ0XpH1QIzLmHEMZn1PukayA+5tBps3SCswnFQC3iSW58N/m2YX2Z37USXQtqG8/HmZTyrUdAzkgMA==</InverseQ><D>hzCUyCjyY/ihdqTnoWqrZFjzBLSg+jX7ZCdsOkFKlvx1i2D/h07hc5x2cq13URTDk6IIJjaTl3NsWdrRk7shv4sXcW5bKg57GPvV6CHRij0Af1xQRLpYsgzeyVjRgKaU+Ea9KZV+mYQ8Ey56krF8MW0/Y4IsVvc1sGWG3HixFEE=</D></RSAKeyValue>";

            RSACryptoServiceProviderrsa = new RSACryptoServiceProvider();

            rsa.FromXmlString(xmlPrivateKey);

 

            byte[]pe = ms.ToArray();

            byte[]sis = rsa.SignData(pe, typeof(System.Security.Cryptography.SHA1));

            txtInfo.Text += ">>> 对合成数据进行签名成功!\r\n";

            txtInfo.Text += ">>> 正在升级...";

            Application.DoEvents();

            intret = +tcu.Update(pe, sis);

            if(ret == 0)

            {

                txtInfo.Text += "成功!\r\n";

            }

            else

            {

                txtInfo.Text += "失败("+ ret.ToString() + ")!\r\n";

            }

        }           

    }

升级演示

1、先运行以太网远程升级示例下的MF程序。这个示例LED灯是慢闪的

2、运行远程升级PC端程序(开发板默认IP为192.168.1.100),连接成功后,选择MFSample目录下的
image.pngimage.png
灯快速闪烁示例,然后远程升级。如果成功,会看到灯快速闪烁。这个时候PC端程序断开连接,重新连接,然后远程部署灯慢速闪烁程序,交换部署,以便更好的观察程序是否远程部署成功。
源码下载
image.png
源码链接:http://www.yfiot.com/MFRelease/Sample/RemoteUpgradeSample.rar


MF简介:http://blog.csdn.net/yefanqiu/article/details/5711770

MF资料:http://www.yfiot.com/DownloadList.asp?Id=2&page=1

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
​从“数据价值”到智能物联网,一条智能制造的升级之路
​从“数据价值”到智能物联网,一条智能制造的升级之路
108 0
阿里云表格存储全面升级,打造一站式物联网存储新方案
阿里云表格存储全面升级,打造一站式物联网存储新方案
410 0
物联网中升级服务为什么如此重要
随着网络环境越来越好,物联网进入快车道,在快速发展过程中,因没有明确的规范和俗成约定,物联网下操作系统是五花八门,例如freeRTOS、RT Thread、AliOS Things、Linux、Android等等,且有些系统是各厂商使用开源代码各自发展,这就注定了系统的多样性,基于这些系统开发的产品那更是数不胜数,这些都直接注定了物联网设备的一个重要特性那就是碎片化严重。
205 0
IoT物联网设备「固件升级」OTA,「资源包更新」最佳实践
IoT物联网设备「固件升级」OTA,「资源包更新」最佳实践
1361 0
阿里云物联网平台OTA动态升级演示
除了静态升级外,物联网平台也可以做动态升级,即设备版本号属于待升级版本时,设备上线即获取云端下发的升级包
871 0
阿里云物联网平台OTA升级平台侧常见问题
关于ota升级可以参考文章https://developer.aliyun.com/article/717007 此篇文章就常见问题归纳总结
704 0
阿里云物联网平台C-SDK 4.x OTA升级示例
本篇文章演示如何使用C-SDK 4.x Demo 做OTA升级
813 0
阿里云物联网平台OTA升级设备端主动申请升级固件测试
完整云端OTA升级可以参考文章 https://developer.aliyun.com/article/717007 本文测试设备主动拉取升级固件的topic 请求Topic:/sys/{productKey}/{deviceName}/thing/ota/firmware/get 响应Topic:/sys/{productKey}/{deviceName}/thing/ota/firmware/get_reply
1335 0
HH
阿里云物联网平台基于MQTT.fx完成OTA升级
物联网平台提供OTA升级与管理服务。下面介绍OTA升级消息的Topic和Alink数据格式,包括设备上报OTA模块版本、物联网平台推送升级包信息、设备上报升级进度和设备请求获取最新升级包信息。
3276 0
阿里云物联网平台高级功能之固件升级
OTA(Over-the-Air Technology)即空中下载技术。阿里云物联网平台支持通过OTA方式进行设备固件升级。本文以MQTT协议下的固件升级为例,介绍OTA固件升级流程、数据流转使用的Topic和数据格式。本文使用MQTT.fx客户端模拟设备,进行固件升级流程的操作演示。
2139 0
+关注
开发者说
文章
问答
视频
来源圈子
更多
阿里云最有价值专家,简称 MVP(Most Valuable Professional),是专注于帮助他人充分了解和使用阿里云技术的意见领袖阿里云 MVP 奖项为我们提供了这样一个机会,向杰出的意见领袖表示感谢,更希望通过 MVP 将开发者的声音反映到我们的技术路线图上。
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
物联网在智慧园区的应用
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
相关实验场景
更多