IOT安全技术综合实验

98 阅读8分钟

一、实验内容

对各种传感器采集到的数据提取出来(2种以上类型数据),进行加密和认证操作,编写网络传输程序,在发送端将加密和认证后的数据发出,在接收端对接收到的数据验证和解密,提取出原始的传感器数据。加密算法和认证算法需要自己编写程序,不得使用网上现有的加密工具,必须有可运行的源代码,可采用DES、AES、RC4等对称加密算法对数据进行加密,采用RSA等公钥密码对数据加密密钥进行加密,采用消息认证码或数字签名机制对数据进行认证。

二、采集数据

1.设备连接:

1.1硬件设备

image.png

1.2气压

image.png image.png  

1.3光强

image.png image.png  

1.4设备连接

image.png image.png

2.实验步骤

2.1光强采集步骤:

1)准备 LiteB(ZigBee)节点、Sensor-A 传感器、Ti 仿真器、DC 12V 电源。

2)完成 LiteB(ZigBee)节点与 Ti 仿真器、MiniUSB 线以及 Sensor-A 传感器的连接。

3)使用电源单独为节点供电,并按下节点电源开关。

4)准备工程:将本实验例程拷贝至非中文路径。

5)编译工程:

使用 IAR 软件打开工程文件,点击菜单栏的:Project ->Make 进行工程编译,提示没有错误即表示工程编译成功。

6)打开串口工具,通过 MiniUSB 数据线将电脑与 LiteB 节点进行连接,打开串口工具并配置其波特率为 38400,8 位数据位,无奇偶校验位,1 位停止位,去除十六进制显示,并打开串口。

image.png

2.2大气气压采集步骤:

1)准备 LiteB(ZigBee)节点、Sensor-A 传感器、Ti 仿真器、DC 12V 电源。

2)完成 LiteB(ZigBee)节点与 Sensor-A 传感器的连接、仿真器、DC 12V 电源和 MiniUSB 线的连接。

3)使用电源为节点供电,并按下节点电源开关。

4)准备工程:将本实验例程:AirPressure 拷贝至非中文路径。

5)编译工程:使用 IAR 软件打开工程文件,进行工程编译,提示没有错误即表示工程编译成功。

6)打开串口工具:通过 MiniUSB 数据线将电脑与 LiteB 节点进行连接,打开串口工具并配

置其波特率为 38400,8 位数据位,无奇偶校验位,1 位停止位,去除十六进制显示,并打开串口

image.png

3.主要代码及注释

3.1光强


  • 名称:main()

  • 功能:程序入口

  • 参数:无

  • 返回:无

******************************************************************************************/

void main(void)

{

float light_data = 0; //存储光照度数据变量

char tx_buff[64]; //串口发送缓冲数组

xtal_init(); //系统时钟初始化

bh1750_init(); //光照度传感器初始化

uart1_init(0x00,0x00); //串口初始化

uart1_send_string("Light Intensity Experiment:\r\n");

while(1)

{

light_data = bh1750_get_data(); //获取传感器数值

sprintf(tx_buff,"Light Intensity Value:%.2f lx\r\n",light_data); //字符串复制

uart1_send_string(tx_buff); //串口打印

memset(tx_buff,0,64); //清空串口缓存

delay_s(1); //延时 1s

}

 

3.2气压


  • 名称:main()

  • 功能:程序入口

  • 参数:无

  • 返回:无

******************************************************************************************/

void main(void)

{

float temperature = 0; //存储温度数据变量

long pressure = 0; //存储压力数据变量

float altitude = 0.0; //存储海拔高度变量

char tx_buff[64]; //串口发送缓冲数组

xtal_init(); //系统时钟初始化

uart1_init(0x00,0x00); //串口初始化

if(fbm320_init() == 1)

uart1_send_string("Airpressure OK!\r\n"); //传感器正常串口打印

else{

uart1_send_string("Airpressure Error!\r\n"); //传感器错误串口打印

}

while(1)

{

fbm320_data_get(&temperature,&pressure); //获取温度压力数据

altitude = (101325-pressure)*(100.0f/(101325 - 100131)); //海拔换算

//将字符串添加到串口发送缓存

sprintf(tx_buff,"Temperature:%.1f℃ Pressure:%0.1fhPa\r\n", temperature,pressure/100.0f);

uart1_send_string(tx_buff); //串口打印

sprintf(tx_buff," Altitude:%0.1f m\r\n",altitude); //将字符串添加到串口发送缓存

uart1_send_string(tx_buff); //串口打印

memset(tx_buff,0,64); //清空串口缓存

delay_s(1); //延时 1s

}

}

三、加密解密算法

1.基本原理

image.png

2.DES加密算法

DES是分组对称加密算法,将64位明文分块。经初始置换打乱,再16轮Feistel迭代:把数据拆左右32位,右半部分经扩展、与子密钥异或、S盒替换(非线性)、P盒置换(线性)后,和左半部分异或,交换左右;最后逆初始置换输出64位密文,56位有效密钥驱动变换。

3.RSA加密算法

挑选两个小素数p和q,在代码中默认p=17,q=19。计算n=pq,n是RSA算法中的模数,也是公钥和私钥的一部分。算出欧拉函数ϕ(n)=(p−1)∗(q−1)。选取一个与ϕ(n)互质的整数e作为公钥指数,代码里e=5。计算私钥指数d,使ed≡1(mod φ(n)),通过扩展欧几里得算法(代码里简单遍历)来求模逆元得到d。

4.主要代码及注释

4.1DES:

class SDES:

    """简化版DES加密算法(64位分组)"""

    def init(self, key):

        self.key = key

        self.round_keys = [key[i:i+1]*4 for i in range(8)]  # 生成轮密钥

 

    def _feistel(self, data, round_key):

        """Feistel轮函数"""

        data_int = int.from_bytes(data, 'big')

        shifted = ((data_int << 1) | (data_int >> 31)) & 0xFFFFFFFF

        shifted_bytes = shifted.to_bytes(4, 'big')

        k_int = int.from_bytes(round_key, 'big')

        return (shifted ^ k_int).to_bytes(4, 'big')

 

    def encrypt(self, block):

        """加密64位数据块"""

        L, R = block[:4], block[4:]

        for i in range(8):  # 8轮加密

            L, R = R, bytes(a^b for a, b in zip(L, self._feistel(R, self.round_keys[i])))

        return R + L  # 最后一轮不交换

 

    def decrypt(self, block):

        """解密64位数据块"""

        L, R = block[:4], block[4:]

        for i in range(7, -1, -1):  # 逆向轮密钥

            L, R = R, bytes(a^b for a, b in zip(L, self._feistel(R, self.round_keys[i])))

        return R + L

 

    @staticmethod

    def pad(data):

        """(PKCS#7填充 确保数据长度是八倍)"""

        pad_len = 8 - (len(data) % 8)

        return data + bytes([pad_len] * pad_len)

 

    @staticmethod

    def unpad(data):

        """(去除填充)"""

        return data[:-data[-1]]

4.2RSA:

class RSA:

    """简化版RSA算法(小素数)"""

    def init(self, p=17, q=19):

        self.n = p * q

        phi = (p-1) * (q-1)

        self.e = 5  # 公钥指数

        self.d = self._mod_inverse(self.e, phi)  # 私钥指数

 

    def _mod_inverse(self, a, m):

        """扩展欧几里得求模逆元"""

        for d in range(1, m):

            if (a * d) % m == 1:

                return d

        return None

 

    def encrypt(self, plaintext):

        """加密字节数据"""

        return [pow(byte, self.e, self.n) for byte in plaintext]

 

    def decrypt(self, ciphertext):

        """解密为字节数据"""

        return bytes(pow(byte, self.d, self.n) for byte in ciphertext)

5.执行界面

发送端: image.png

接收端: image.png

四、消息认证

1.认证方式

对数据进行 PKCS#7 填充,确保数据长度是 8 的倍数。初始化 MAC 值为全 0 字节。按 8 字节分块遍历数据,将每块与当前 MAC 值异或。使用 SDES 算法对最终异或结果加密得到 MAC 值。发送端生成对称密钥加密数据后,调用MAC.compute计算加密数据的 MAC 值,并将加密后的对称密钥、MAC 值和加密数据一起发送。接收端接收数据后,解密对称密钥,使用相同密钥和算法重新计算MAC值,并与接收到的MAC值比较。

2. 主要代码实现

class MAC:

    """(基于DES的MAC认证算法)"""

    @staticmethod

    def compute(key, data):

        """(计算消息认证码)"""

        data = SDES.pad(data)

        mac = b'\x00' * 8

        sdes = SDES(key)

        for i in range(0, len(data), 8):

            block = data[i:i+8]

            mac = bytes(a^b for a, b in zip(mac, block))

        return sdes.encrypt(mac)

五、网络传输

本次实验的网络传输主要通过 Python 的socket库实现,结合自定义的NetworkUtils类进行数据的发送和接收在发送端。

在发送端,主要通过以下步骤完成网络传输:

1.创建套接字:使用socket.socket方法创建一个 TCP 套接字对象。

2.连接服务器:使用connect方法连接到指定的服务器 IP 地址和端口。

3.发送数据:使用NetworkUtils.send_data方法发送加密后的对称密钥、MAC 值和加密数据。

其中,NetworkUtils.send_data方法会在数据前添加长度头,确保接收端能够正确接收完整的数据。

在接收端,主要通过以下步骤完成网络传输:

1.创建套接字并绑定监听:使用socket.socket方法创建一个 TCP 套接字对象,并绑定到指定的端口进行监听。

2.接受客户端连接:使用accept方法接受客户端的连接请求,并为每个客户端创建一个新的线程进行处理。

3.接收数据:使用NetworkUtils.recv_data方法接收加密后的对称密钥、MAC值和加密数据。

其中,NetworkUtils.recv_data方法会先接收长度头,然后根据长度头接收完整的数据。

六、总结与收获

本次实验围绕传感器数据安全传输,借助crypto_utils.py实现核心加密认证。DES类完成64位数据块加解密及填充处理,RSA实现简化密钥加密。MAC类计算消息认证码保证数据完整,NetworkUtils负责网络通信数据收发。结合send.py与receive.py的GUI界面,完成数据从发送端加密传输到接收端解密验证保存的全流程,让我掌握加密算法与网络编程实践,提升项目开发能力。感谢老师的指点与教育,让我对网络安全有更深入的了解。