数据处理思想和程序架构: 使用Mbedtls包中的SSL,和服务器进行网络加密通信
<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/单片机知识点总结/directory.html" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
单向认证忽略认证方式
1.首先保证自己的程序已经实现了普通TCP连接通信
确保自己的单片机的程序存储空间在60KB以上!
确保自己的单片机有至少64KB及其以上的RAM空间!
如果使用的STM32那么推荐的型号为 STM32F103RFT6/RGT6/VFT6/VGT6/ZFT6/ZGT6
为了保证此篇文章能够让所有人都能应用,我就假设我的程序里面已经实现了TCP连接\
然后规定:
/*假设接收网络数据函数*/ int net_recv(char *data); /*假设TCP发送数据函数*/ int net_send(char *data,int len);
2.按照上一节 把MBEDTLS包添加到工程
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
4.编译一下
5.方式1:修改一下源码即可
方式2:如果不愿意修改源码可以 选择C99模式
6.再编译一下
7.增加自己的随机数函数 和 时间戳返回函数
/*随机数函数*/ int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ) { unsigned long randomValue = ((rand()*20) + 1000);//生成随机数 ((void) data); *olen = 0; if( len < sizeof(unsigned long) ) return( 0 ); memcpy( output, &randomValue, sizeof(unsigned long) ); *olen = sizeof(unsigned long); return 0; } /** * @brief 时间函数(SSL底层会调用时间验证证书是否过期) **/ //struct tm *lcTime; //time_t startTime; // lcTime = localtime (&startTime); _ARMABI time_t time(time_t *t) { // time_t it; if (t) { return *t; } else { // startTime = 0; // lcTime = localtime (&startTime); // it = mktime(lcTime); // return it ; return 0; } }
8.增加SSL底层获取数据函数
咱们在后面设置好SSL接收回调函数以后, SSL底层会调用 custom_ssl_recv 函数
SSL底层要多少个数据,咱们才返回多少个数据,这是SSL底层规定的,所以为了配合SSL底层,程序写的比较多.
SSL底层调用的时候最后一个参数 size_t len是指定要多少个数据.
/** * @brief 自定义接收函数(把自己的接收函数放到此函数中) * @param None * @param None * @param None * @retval None * @example **/ int net_recv_data_len=0; int net_recv_data_len_count=0; char net_recv_buff[2000]; static int custom_ssl_recv( void *ctx, unsigned char *buf, size_t len ) { int rbCanReadLen; if(net_recv_data_len ==0) { net_recv_data_len=net_recv(net_recv_buff);//调用自己的函数接收数据 if(net_recv_data_len>0)//有数据 { if(len >= net_recv_data_len)//希望读取的数据个数大于实际的数据个数 { len = net_recv_data_len; memcpy(buf, net_recv_buff, len); net_recv_data_len = 0; net_recv_data_len_count=0; return len; } else//实际的数据个数比希望读取的多 { memcpy(buf, net_recv_buff, len); net_recv_data_len_count = len; return len; } } else { return MBEDTLS_ERR_NET_RECV_FAILED; } } else { if(len >= net_recv_data_len - net_recv_data_len_count)//希望读取的数据个数大于实际的数据个数 { len = net_recv_data_len - net_recv_data_len_count; memcpy(buf, net_recv_buff+net_recv_data_len_count, len); net_recv_data_len = 0; net_recv_data_len_count=0; return len; } else//实际的数据个数比希望读取的多 { memcpy(buf, net_recv_buff + net_recv_data_len_count, len); net_recv_data_len_count = net_recv_data_len_count + len; return len; } } }
9.增加发送函数以供SSL底层调用
/*增加发送函数*/ static int custom_ssl_send( void *ctx, unsigned char *buf, size_t len ) { ctx = ctx; net_send(buf,len);//调用自己的TCP发送函数 return (int)len; }
10,定义需要的变量,并初始化SSL
11.关于 替换自己证书的CN字段
看上一节
12,连接上TCP以后,等待SSL握手成功
13,发送和接收数据
3.如果不能连接,可以打开DEBUG
#define MBEDTLS_DEBUG_C
4.配置DEBUG
/*设置 debug 输出函数*/ static void my_debug( void *ctx, int level, const char *file, int line, const char *str ) { printf("%s:%04d: %s\r\n", file, line, str ); }