物联网将会成为继互联网之后的下一个暴发点,目前以有不少公司已进入该领域。
智能家居作为物联网中最具有潜力的领域,网络安全是必须引起重视的课题。在互联网领域中,用户去安全性的敏感度并不是那个高。但是在智能家居领域中,如果系统被黑客攻击:半夜房门自动打开、无故解除安防系统、灯不亮等严重威胁到了用户的财产人身安全。
所以,智能家居想发展,安全性是决不可忽视的关键要素。
任何信息在网络上传播能是能被第三者监听的。
一个局域网就像是一间会议室,里面坐了几个人,大家坐在一起相互交流。同时只允许一个人发言,不管是谁说话都能被在场的所有人听见。
通常情况下,只有被交流的对象才会在意对方说的话,其他人不会留意。
比如:屋子里有a,b,c,d四个人。如下是a与b之间的对话:
a:嘿b
b:嘿a
a:“告诉我银行卡密码吧”
b:“123321”
由于a不是对c与d说的话,c与d自然忽略这句话,但是他们是能听得见的!
如果d是一个不怀好意的人,刻意留心他们的对话,是很容易窃听到关键信息的。
而且网络里还有arp诈骗等手段,网络安全是岌岌可危的。
怎么办?两种思路:
就是不允许其它结点加入到局域网中来。
在wifi普及面非常广的时代,家家都有无线路由器,这要求用户严守wifi密码,严防泄漏。
这比较难,有时候wifi密码会在用户不知情的情况下泄漏。比如市面上存在一种叫“wifi万能钥匙”,这就是一种盗取用户已登陆wifi结点密码并共享给其它人的工具。这说明这个方法很难把控。
至于如何在这方面有所提升,已超出了我们智能家居所负责的领域。暂不讨论~
做不到被听到,那就不让第3个人听懂也行。会议室里有a,b,c 3个人,a与b对英语交流,c在旁听到了,但不知道他们在说什么。
这是我们在安全方面可以做的。
该智能家居系统组织如下:
server: 云端服务器
smarthost: 智能主机,负责将以太网中的数据能过zigbee数据转发给device
device: 设备结点,常见的有灯、窗帘、门磁感应器,与smarthost通过zigbee连接
client: 手机应用,有android客户端与ios客户端。接受用户的指令。当client与smarthost在同一局域网中,client通过wifi与smarthost进行交互;如果不在同一个局域网,则通过与server进行转发。
假设局域网中来了一个不速之客hacker,它启图操控家居设备。
如果client与smarthost之间的通信是明文的,那么没有安全性可言。只要黑客进入了家里的局域网,对网络包进行监听,很轻易地操控家里的设备。
client-->smarthost: <code>login: account john, password abc</code>
smarthost-->client: <code>ok</code>
client-->smarthost: <code>open the door</code>
smarthost-->client: <code>done</code>
hacker监听到上面的通信,hacker可以进行模拟client进行登陆
hacker-->smarthost: <code>login: account john, password abc</code>
smarthost-->hacker: <code>ok</code>
hacker-->smarthost: <code>open the door</code>
smarthost-->hacker: <code>done</code>
于是门开了。
由于是明文,稍有头脑的hacker就能分析出client与smarthost的通信协议。在盗取了用户的帐号与密码之后,hacker就可以完全掌据整个家居系统。
防预级别:v 只能抵挡没有网络基础的攻击
由于上面问题的是明文数据传输,容易被hacker分析。于是在上一版本的基础上使用特定的密钥对数据进行加密。
如下用()表示其中的内容是用static_key加密的
client-->smarthost: <code>(login: account john, password abc)</code>
smarthost-->client: <code>(ok)</code>
client-->smarthost: <code>(open the door)</code>
smarthost-->client: <code>(done)</code>
由于上面是用密文进行通信的,hacker不知道其容易是什么意思。但是,他知道只要把上面的话录制下来,重复播放一便就可以伪装client开门了。
hacker-->smarthost: <code>(login: account john, password abc)</code>
hacker-->smarthost: <code>(open the door)</code>
结果门开了。
其实hacker不知道client与smarthost的具体内容是什么。他可能猜到是在登陆系统,然后是发命令开门的动作。但他无法得知通信的结构,也无法获取用户的帐号与密码。它只能说模仿client的“发音”与smarthost进行对话,达到控制设备的目的。
针对上面hacker的攻击,我们做了改进。通常,hacker不会在监听到了命令之后立即执行。而是在等主人不在家了再执行上面的开门命令。那么,我们在密文域中加一个字段:timestamp(时间戳)。
client-->smarthost: <code>(201509261543, login: accout john, password abc123)</code>
smarthost接收到命令,当前系统时间为2015-09-26 15:44,与client提供的命令误差在5分钟以内,通过检查。
smarthost-->client: <code>(201509261544, ok)</code>
client接收到命令,当前系统时间为2015-09-26 15:43,与client提供的命令误差在5分钟以内,通过检查。
client-->smarthost: <code>(201509261548, open the door)</code>
smarthost接收到命令,当前系统时间为2015-09-26 15:49,与client提供的命令误差在5分钟以内,通过检查。
smarthost-->client: <code>(201509261549, ok)</code>
client接收到命令,当前系统时间为2015-09-26 15:48,与client提供的命令误差在5分钟以内,通过检查。
hacker监听到了上面的整个过程,在主人离开了家,在21:09实施攻击。
hacker-->smarthost: <code>(201509261543, login: accout john, password abc123)</code>
smarthost接收到命令,当前系统时间为2015-09-26 21:09,与hacker提供的命令误差超出5分钟,丢弃。
攻击失败。
由于hacker不知道static_key,不知道client-->server的明文是什么。所以他无法提取其中的帐号与密码信息。同时,他也没有办法更改密文中的timestamp。所以,无法成功突破。
通抵御普通的hacker攻击在时间间隔较长的指令伪装攻击。
上面的方式能抵挡超过5分钟的命令伪装,但是不能解决5分钟内的命令伪装问题。于是,我们在上一版的基础上,在指令中加添了serial域,即序列号,用于防止短时间内的重复指令。
在通信中,我们会随机生成一个serial:xxxxxxx,接收方收到指令后,会去查 serialtable看5分钟内有没有xxxxxxxxx存在。
如果没有找到,则处理该命令,然后将xxxxxxx加入到serialtable中。 如果找到,则丢弃该指令。
由于系统只保存5分钟的serial,不会有太大的查表负担。
如此与时间戳结合使用,便可以彻底解决hacker伪装命令的问题。
与timestamp相似,由于hacker无法获得明文,所以他没有办法修改里面的timestamp与serial。将已发送过的数据包再发一次,必然导致失败。
上面的安全措施看起来比较完善了。但是,它有3个前提条件:
加密算法过于强硬,无法逆运算
暴力破解代价大
第三方无法获得通信的加密算法与密钥
对于问题1,我们可能采用国际上公认的加密算法进行加密,如openssl中的aes。
对于问题2,我们可以使得加密的密钥过于复杂,比如128字节的密钥进行加密。如果使用暴力破解,其代价太大。
问题3是最大的问题。
有句话叫作:“日防夜防,家贼难防”,由于用于加密的密钥是写在代码里的。开发工程师是再清楚不过了,加密的密钥非常容易泄漏。
一旦static_key泄密,那么所有的加密如同没有加密!hacker所向披靡如入无人之地
不允许普通的开发工程师涉及加密算法与加密密钥。将加密算法的设计实现工作交给公司核心人士去实现。其它普通的研发工程师只能拿到一个二进制的静态库或动态库。
但这也有一点需要注意的,不管是生成什么样的加密过程,加密的密钥必须不能是明文。比如:
因为生成的二进制文件里有保存明文,可以轻易地用工具搜出来。如:
就会列出库中的所有明文。好奇心强的工程师很容易地就从中找出你的加密密钥了。
就算工程师没有泄密,hacker自己去买台smarthost,对程序用<code>strings</code>分析,也是能很轻松找出static_key的。
必须是动态生成的。如:
这样,不能轻而易举地获取到。但是,这也不是说获取不到了,只要单步跟踪调试,也能获取,只是麻烦了点。
信条:不能将加密算法设计者自己挡在外的加密算法不是好算法!
摒弃static_key的加密方法,每个产品在出厂时都有一个特有密钥unique_key,并且在服务器的数据有表。
以下以[]表示被unique_key加密的数据
用户购买了smarthost后,smarthost首次启动,登陆server。
smarthost-->server: <code>(uid=xxxxxxxx)[timestamp=201509291255, serial=82342, i am smarthost, model=m1, log in]</code>
注意:smarthost在介绍自己uid时是用static_key加密,之后使用unique_key加密。
server-->smarthost: <code>[allow]</code>
server从数据包中提取了uid,从数据库中查找到对应uid的unique_key,用unique_key加密回复的数据。
之后的数据包都是用smarthost的unique_key进行加密。
如此,只有数据库的super administor有权限得知对应uid smarhost的unique_key。
用户要使用client绑定smarthost,但client本身不知道smarthost的uid,也不知道smarthost的unique_key。如何与smarthost通信?
在 smarthost 的背后有一个二维码,就是该smarthost的unique_key。用户用client上的二维码扫扫功能,获取该smarthost的unique_key。
通信过程:
搜索smarthost
client用udp广播数据包:<code>[timestamp=201509291255, serial=24234, tell me your ip address]</code>
smarthost收到数据包后,用unique_key进行解密,验证timestamp域,发现结果正常 ,表示解密成功,证明该数据包正是发给自己的。于是回复udp包:<code>[timestamp=201509291255, serial=3234, ip_address=192.168.x.x]</code>
client收到udp数据包,用unique_key进行解密,得到了smarthost的ip地址。
如果同时出现2个以上的smarthost,只有使用了对应unique_key的smarthost才能通过timestamp验证(错误的unique_key解密所得的timestamp是没法通过时间戳验证的)。
绑定smarthost
后面的与主机交互过程都使用unique_key进行加密。
用password的md5sum当作unique_key进行通信,默认带timestamp与serial验证。
注册帐号
client-->server: (regist: account=lucy, password=98789) server-->client: (done)
服务器在接收到该注册信息后,会将password的md5sum作为unique_key与client进行数据加密。以下以[]表示用unique_key加密的数据。
在注册时,加密等级是很低的。
登陆
client-->server: (login: account=lucy)[timestamp=201509292100] 告诉server自己的account,然后server根据account到数据库查
表,获得unique_key,并用其解密timestamp,再进行时间域校验。通过则表示登陆成功,否则表示失败。
server-->client: [timestamp=201509292100, ok]
对于不了解通信协议的hacker,即使使用包伪装与重发包的方式已经是束手无策了。
这里的hacker,是指协议的设计者或对协议非常熟悉的人,假设他们:
已获得static_key与加密解密算法
不能接触到服务器与机密数据
不能接触到用户手上的smarthost
行动:
假设hacker已通过某种方法加入了smarthost的局域网。
通过监听器,捕获到了smarthost的登陆包,得到smarthost的uid。由于没有unique_key,得不到smarthost与服务器的通信内容。但他知道密文解密后的明文内容,可能使用暴力破解法进行破解。但是时间成本太高。
如果监听到client的注册过程就可以,因为注册数据包是用static_key加密的,可以破解。hacker可以获得用户的密码,进而算出md5sum的unique_key的。用这个来伪装真正的client,对smarthost进行操控。
此方法的关键点在于要抓到注册数据包,一个用户只有一次,而且要在与hacker所在局域网中进行才有可能被抓到。如果打算对smarthost进行攻击时,用户早都已经注册了帐户。
诱使用户使用盗号码木马app,从client的手机中窃取client保存在手机系统中的文件。从而获取client的帐号密码,以及smarthost的unique_key。
从上可得出,通过监听方式来破解似乎只有暴力破解法了。而更可行的破解方案还是盗号木马。
因为我们总得在手机上保存主机的unique_key与用户的帐号与密码。否则就得每次让用户去扫smarthost背后的二维码,每次都让用户重新输入帐号密码登陆。用户肯定受不了。
关于上面的安全性问题该如何解决,博主还没有想到合理的解决方案,欢迎讨论。上面的讨论如有纰漏,欢迎指正。
博主从事智能家居领域研发,欢迎关注!