摘要:
随着智能家居的普及。安全性问题的研究已成当务之急。针对物联网网关自身的易受攻击性和网络传输过程中的信息窃听,我们分别採用SHA-1和AES算法对网关中的操作系统和节点採集的信息进行验证和加密,在一定程度上实现可信。我们创造性地将可信模块与网关平台进行解耦,利于可信模块的升级和维护。
简单介绍:
智能家居通过物联网技术将家中的各种设备(如照明系统、空调控制、安防系统)连接到一起。智能家居最初的发展主要以灯光遥控、电器远程控制和电动窗帘控制为主,后来延伸到家庭安防报警、背景音乐、可视对讲、门禁指纹控制等领域。
可见智能家居中的中央控制系统已经担当起大管家的职责,然而随之而来的安全性问题日益突出,须要我们对大管家进行特殊的防护。
物联网网关,作为一个新的名词。在未来的物联网时代将会扮演很重要的角色。它将成为连接感知网络与传统通信网络的纽带。作为网关设备,物联网网关能够实现感知网络与通信网络。以及不同类型感知网络之间的协议转换。既能够实现广域互联.也能够实现局域互联。物联网网关在智能家居中处于核心地位,在我们的设计中网关便担当了大管家的职责,因此我们将重点针对物联网网关进行防护。
可信计算是在计算和通信系统中广泛使用基于硬件安全模块支持下的计算平台。以提高系统总体的安全性与可靠性。
可信计算包含5个完整的可信系统所必须的关键技术概念:签注密钥、安全输入输出、储存器屏蔽、密封储存、以及远程认证。因此将可信计算用于物联网网关,实现一套完毕的物联网网关可信平台模块。而眼下国内还暂无技术较成熟的基于可信计算的物联网网关平台,项目较为新颖。
系统设计:
将可信平台模块(TPM)用于对嵌入式物联网网关设备的安全管理。实现网关的安全信息处理及通信。我们设计并在Devkit8500平台上实现了TPM模块的主要基本功能,并搭配基于ARM9的TQ2440平台的嵌入式物联网网关以及基于Zigbee通信协议的无线传感器网络。通过TPM模块对网关启动时(包含Boot Loader以及OS Kernel)的完整性验证,能够在启动前保证网关的核心系统程序的安全性。同一时候。网关应用程序(传感器数据收集、Web Service等)对数据的处理以及同外部设备通信也将通过TPM模块进行加解密处理,以保证数据的安全性。
功能模块设计:
1、TPM模块:
1)通过RS232与网关进行通信。
2)上面运行SHA-1验证算法,当网关启动时,网关会先后将其操作系统的bootloader和kernel通过RS232串口传送到TPM。届时SHA-1算法利用传来的信息生成信息摘要并与正确摘要匹配达到开机可信验证的目的,这是针对对物联网网关系统级的攻击的防护,一旦系统发生修改,SHA-1验证算法便会检測到异常。提醒用户。
3)AES加密算法。主要针对传感网节点传来的信息,若以明文存在网关数据库中。相同面临被窃取的风险。我们借鉴https的加密策略。在TPM上集成AES加密算法,节点传来的信息经由TPM进行加密,以密文的信息存在网关上的sqlite数据库中。
2、网关模块:
1)搭载GoAhead webserver。并编写CGI程序作为逻辑与界面控制。
2)通过RS232与TPM通信,并与温湿度传感器节点组成的Zigbee网络中协调器 进行RS232通讯。
3)自己定义通信协议,实现网关与TPM通信的有序性。
当两路或多路节点信息同一时候经由TPM进行加密处理时。它们是在争用一条串口线。这时就须要定义规则,对多路信息进行惟一标识和排队等候。
3、用户端:
通过訪问网关上的CGI页面,用户先进行身份验证,然后可选择是否将请求信息进行AES加密处理。防止用户指令遭窃听。大规模用户訪问对可信模块的计算能力提出了严峻的挑战。而实现的TPM和网关的解耦。却不利于大规模用户訪问,也造成了性能瓶颈。
4、传感节点:
温湿度传感器配备Zigbee通信模块,组建传感网。协调器节点负责发起并维护一个无线网络。识别网络中的设备增加网络;路由器节点支撑网络链路结构,完毕数据包的转发。终端节点是网络的感知者和运行者,负责数据採集和可运行的网络动作。
总结:
针对智能家居。我们搭建了一个模拟环境,建立起TPM负责可信验证,实现节点信息的安全存储、用户訪问信息的加密传输以及系统级的可信验证,并对大规模訪问有所探究。同一时候涉及Zigbee网络的组建,而解耦设计能够对TPM进行单独维护和升级。我们所构建的原始模型。不仅能够用于开发智能家居,并且我们曾将这一模型用于火车站自己主动检票机的设计。这也是我们大胆的将可信计算平台应用于物联网网关设计的一次尝试。
附:
AESListen.c
/********************************************************* *TPM AES jiemi ***********************************************************/#includeListenarm.c#include #include #include #include #include #include #include #include #include #include #include "aes.h"#define FALSE -1#define TRUE 1int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, }; int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; void set_speed(int fd, int speed); int set_Parity(int fd,int databits,int stopbits,int parity);void Print(BYTE a[]){ int i; for(i=0; i<4*Nb; i++) { printf("%02X ", a[i]); } printf("\n\n");}int main(void){ char *serialport="/dev/ttyUSB0"; int fd; int nread; int count; char buffer[16]={'\0'}; char buffer_all[16]={'\0'}; fd=open(serialport,O_RDWR|O_NOCTTY|O_NDELAY); if(fd==-1) { printf("%s open error!\n",serialport); return -1; } printf("open %s successfully !",serialport); fflush(stdout); set_speed(fd,115200); if (set_Parity(fd,8,1,'N')==FALSE) { printf("Set Parity Error\n"); exit(1); } DWORD e_key[Nb*(MaxNr+1)]; BYTE key[4*MaxNk]={ //miyao 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; BYTE decrypted_msg[4*Nb]; int filelen; int times=0; SetKey(192); KeyExpansion(key, e_key); tcflush(fd,TCIOFLUSH); count=0; while(1) { nread=read(fd,buffer,16); if(nread>0) { memcpy(buffer_all+count,buffer,nread); count +=nread; } if(count==16) { printf("total_size : %d\n",count); break; } sleep(1); printf("loop one second\n"); } printf("encrypted message:\n"); Print(buffer_all); AesDecrypt(buffer_all, decrypted_msg, e_key); //jiemi printf("decrypted message:\n"); Print(decrypted_msg); write(fd,decrypted_msg,16); return 0; }void set_speed(int fd, int speed) { int i; int status; struct termios Opt; tcgetattr(fd, &Opt); for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); /* */ cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); /* */ if (status != 0) { perror("tcsetattr fd1"); return; } } tcflush(fd,TCIOFLUSH); /* */ } } int set_Parity(int fd,int databits,int stopbits,int parity) { struct termios options; if (tcgetattr( fd,&options) != 0) { printf("SetupSerial 1"); return(FALSE); } options.c_cflag &= ~CSIZE; /* */ switch (databits) /**/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size\n"); return (FALSE); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* */ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* */ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: fprintf(stderr,"Unsupported parity\n"); return (FALSE); } /**/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits\n"); return (FALSE); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; options.c_cc[VTIME] = 150; // 15 seconds options.c_cc[VMIN] = 0; options.c_lflag &= ~(ICANON |ISIG); options.c_iflag &= ~(ICRNL|IGNCR); tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */ if (tcsetattr(fd,TCSANOW,&options) != 0) { printf("SetupSerial 3"); return (FALSE); } return (TRUE); }
#includeCGI.c#include #include #include #include #include #include #include #include #include #include #include "sha1.h"#include "stdint.h"#define MAX 1024 #define FALSE -1 #define TRUE 1 #define BUFFER_SIZE 1024typedef unsigned char TPM_TAG ;typedef unsigned int UINT32;typedef unsigned char TPM_COMMAND_CODE;int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, }; int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; void set_speed(int fd, int speed); int set_Parity(int fd,int databits,int stopbits,int parity); void itoa ( unsigned int val, char *buf, int radix );unsigned char buffer_all_bootloader[1024*1024];int buffer_len_bootloader;unsigned char buffer_all_kernel[1024*1024];int buffer_len_kernel;unsigned char Message_Digest_bootloader[SHA1HashSize];unsigned char Message_Digest_kernel[SHA1HashSize];typedef struct { TPM_TAG tag; UINT32 paramSize; TPM_COMMAND_CODE ordinal;}TPM_COMMAND;//unsigned char bootloader_sha1_checksum[20]={31,79,191,25,22,207,68,233,254,242,171,148,233,85,122,172,52,150,227,121};unsigned char bootloader_sha1_checksum[20]={0x77,0xCA,0x04,0xD2,0x41,0xA7,0xF7,0xCD,0x9F,0x69,0x11,0x06,0x68,0x28,0x95,0xE3,0x71,0x7F,0x24,0xEC};//unsigned char kernel_sha1_checksum[20]={161,76,7,206,132,245,247,137,244,45,3,48,49,98,232,213,32,219,62,17};unsigned char kernel_sha1_checksum[20]={0x70,0xD0,0x0C,0x51,0x7C,0x10,0xFB,0xCB,0x93,0x81,0x2C,0x0C,0x5C,0x8C,0xBF,0x35,0x23,0xB8,0xE5,0x99};int main(void){ char *serialport = "/dev/ttyUSB0"; int fd=open(serialport,O_RDWR,O_NOCTTY); if(fd == -1) { printf("%s Open Error!\n",serialport); return -1; } printf("open %s successfully !\n",serialport); fflush(stdout); set_speed(fd,115200); if (set_Parity(fd,8,1,'N')== FALSE) { printf("Set Parity Error\n"); exit(1); } /*******************************************************************************/ struct timeval tpstart,tpend; float timeuse; gettimeofday(&tpstart,NULL); write(fd,"s",1); /*TPM帧格式*/ TPM_COMMAND request_bootloader={'t',6,'s'}; unsigned char d[5]; itoa(request_bootloader.paramSize,d,10); unsigned char dest[strlen(d)+5]; sprintf(dest,"%c%d%c",request_bootloader.tag,request_bootloader.paramSize,request_bootloader.ordinal); dest[3]='a'; dest[4]='b'; dest[5]='c'; write(fd,dest,strlen(d)+5); /*******************************************************************************/ //监听bootloader int nread = 1,nwrite = 0; int total_size = 0; unsigned char buffer[BUFFER_SIZE] = {'\0'}; int i; buffer_len_bootloader = 0; while(1) { nread=read(fd,buffer,1024); if(nread>0) { total_size+=nread; memcpy(buffer_all_bootloader+buffer_len_bootloader,buffer,nread); buffer_len_bootloader+=nread;#if 0 for(i = 0;i 0) { total_size+=nread; memcpy(buffer_all_kernel+buffer_len_kernel,buffer2,nread); buffer_len_kernel+=nread;#if 0 for(i = 0;i 9)*p++ = (char)(digval - 10 + 'a'); /* a letter */ ///else*p++ = (char ) (digval + '0'); /* a digit */ } while (val > 0);/* We now have the digit of the number in the buffer, but in reverseorder. Thus we reverse them now. */*p-- = '\0'; /* terminate string; p points to last digit */ /do {temp = *p;*p = *firstdig;*firstdig = temp; /* swap *p and *firstdig */--p;++firstdig; /* advance to next two digits */} while (firstdig < p); /* repeat until halfway */}
/***************** * CGI * *******************/#include#include #include #include #include #include #include #include #include #include #include #define MAX 1024 #define FALSE -1 #define TRUE 1 #define BUFFER_SIZE 1024typedef unsigned char BYTE;int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, }; int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; void set_speed(int fd, int speed);int set_Parity(int fd,int databits,int stopbits,int parity);void Print(BYTE a[]){ int i; for(i=0; i<4*4; i++) { printf("%02X ", a[i]); } printf("\n\n");}int main(){ char *method; char *data; int count; int i; int j; char *serialport = "/dev/tq2440_serial1" ; // int fd; int nread; char buffer[16] = {'\0'}; char buffer_all[16]={'\0'}; FILE *fp; time_t rawtime; struct tm *timeinfo; int end=5; printf("Content-type:text/html\n\n"); printf(" this is a cgi"); if((method=getenv("REQUEST_METHOD"))==NULL) // return 1; printf("
method: %s",method); if((data=getenv("QUERY_STRING"))==NULL) // return 1; printf("
%s",data); /*if((i=sscanf(data,"command=%s",command))==0) return 1; printf("%s",command);*/ /************************** * * * **************************/ fd=open(serialport,O_RDWR|O_NOCTTY|O_NDELAY); if(fd == -1) { printf("%s Open Error!\n",serialport); return -1; } printf("
open %s successfully !",serialport); set_speed(fd,115200); if (set_Parity(fd,8,1,'N')== FALSE) { printf("Set Parity Error\n"); exit(1); } tcflush(fd,TCIOFLUSH); write(fd,data,16); count=0; while(end) { end--; nread=read(fd,buffer,16); if(nread>0) { memcpy(buffer_all+count,buffer,nread); count += nread; } if(count==16) { printf("
receive success !"); break; } sleep(1); printf("
loop one time"); } Print(buffer_all); time(&rawtime); timeinfo=localtime(&rawtime); if((fp=fopen("/mnt/usrcommand.txt","ab+"))==NULL) return 1; fprintf(fp,"%4d-%02d-%02d %02d%02d%02d\n",1900+timeinfo->tm_year,1+timeinfo->tm_mon,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec); //fwrite(data,sizeof(char),strlen(data),fp); for(j=0; j<4*4; j++) { fprintf(fp,"%02X",buffer_all[j]); } //fwrite(buffer_all,sizeof(char),16,fp); fclose(fp); return 0; }void set_speed(int fd, int speed) { int i; int status; struct termios Opt; tcgetattr(fd, &Opt); for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); /* */ cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); /* */ if (status != 0) { perror("tcsetattr fd1"); return; } } tcflush(fd,TCIOFLUSH); /* */ } } int set_Parity(int fd,int databits,int stopbits,int parity) { struct termios options; if (tcgetattr( fd,&options) != 0) { printf("SetupSerial 1"); return(FALSE); } options.c_cflag &= ~CSIZE; /* */ switch (databits) /**/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size\n"); return (FALSE); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* */ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: fprintf(stderr,"Unsupported parity\n"); return (FALSE); } /**/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits\n"); return (FALSE); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; options.c_cc[VTIME] = 150; // 15 seconds options.c_cc[VMIN] = 0; options.c_lflag &= ~(ICANON |ISIG); options.c_iflag &= ~(ICRNL|IGNCR); tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */ if (tcsetattr(fd,TCSANOW,&options) != 0) { printf("SetupSerial 3"); return (FALSE); } return (TRUE); }