查看: 1493|回复: 0

[技术交流] IOT-WiFI-mbedTLS协议(2)

[复制链接]

185

主题

204

帖子

596

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
596
发表于 2021-4-16 15:20:05 | 显示全部楼层 |阅读模式
  三、mbedTLS

  随着物联网的发展,设备节点的安全问题也越来越重要,相比互联网的openSSL,物联网的嵌入式设备适合小巧灵活的MbedTLS,曾用名PolarSSL,可以根据需求进行配置,降低对硬件资源的消耗。mbedtls内置了非常多的加密解密,散列算法源码,即使不使用tls加密,也从里面挖掘各种算法,诸如AES/RSA/MD5等。但是openSSL功能更强大,进入https://tls.mbed.org/,点击download,在https://github.com/ARMmbed/mbedtls下载源码。

  mbedTLS移植

  mbedtls是一款采用Apache 2.0许可证协议开源软件加密库,使用标准C语言编写;独立的模块设计,降低模块之间的耦合度。从功能上看,主要包括加密库、X509证书、SSL/TLS协议三部分。
  1、先加载各种证书、秘钥,配置opt结构体成员初始化,如TLS版本,加密套件类型等
  2、然后开始连接服务器 mbedtls_net_connect
  3、初始化tls参数 mbedtls_ssl_config_defaults,设置网络收发回调函数等
  4、SSL/TLS握手流程,过程比较复杂,简化就是通信双方校验对方身份,获取对方的公钥,确认加密方式,后续数据进行加密或解密做准备 mbedtls_ssl_handshake
  5、校验服务端返回的证书 mbedtls_ssl_get_verify_result
  6、如果前面流程顺畅,就可以使用mbedtls_ssl_write,mbedtls_ssl_read收发数据了
  7、测试结束后的清理工作
  8、与标准socket编程对比,接口存在一定的对应关系:

  网络接口
  
  mbedtls默认的网络接口mbedtls/library/net_socket.c,可以在windows下运行,特别注意,默认的socket操作都是阻塞模式;一般不适合ARM平台,关闭MBEDTLS_NET_C,结合硬件平台重新实现网络接口。主要包括以下函数:
  void mbedtls_net_init( mbedtls_net_context *ctx );
  int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto );
  int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len );
  int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, uint32_t timeout );
  int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
  void mbedtls_net_free( mbedtls_net_context *ctx );

  若需要DUP版本的DTLS,还需要实现该文件下另外几个接口,具体流程参考dtls_client.c。

  自定义实现的网络收发接口,需要注册mbedtls_ssl_set_bio告知底层。

  mbedtls_ssl_set_bio(&ssl, &server_fd,
   mbedtls_custom_send,//改写后的mbedtls_net_send,为底层提供发送接口
   mbedtls_custom_recv,//为底层提供接收接口
   mbedtls_custom_recv_timeout)   

  内存管理接口

  void* calloc(unsigned int num,unsigned int size)
  void free(void * ptr)
   mbedtls_platform_set_calloc_free(custom_calloc, custom_free)

  定时器接口

  #if defined (__MBEDTLS_DTLS__)
  //Set delays to watch
  void platform_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms)
  {
   platform_timing_delay_context *ctx = (platform_timing_delay_context *) data;
        
   ctx->int_ms = int_ms;
   ctx->fin_ms = fin_ms;
        
   if(fin_ms != 0)
   {
    ctx->snapshot = custom_get_systicks();
   }   
  }   

  //Get number of delays expired
  int platform_timing_get_delay(void *data)
  {
   platform_timing_delay_context *ctx = (platform_timing_delay_context *) data;
   unsigned long elapsed_ms;
        
   if(ctx->fin_ms == 0)
   {
    return(-1);
   }
        
   elapsed_ms = custom_ticks_to_milli_secs(custom_get_systicks() - ctx->snapshot); //转换成毫秒
        
   if(elapsed_ms >= ctx->fin_ms)
   {
    return(2);
   }
        
   if(elapsed_ms >= ctx->int_ms)
   {
    return(1);
   }
        
   return 0;
  }

  #endif /* __MBEDTLS_DTLS__ */
   
  //注册到底层
  mbedtls_ssl_set_timer_cb( &ssl, &platform_timer, platform_timing_set_delay, platform_timing_get_delay );

  证书和密钥

  在源码programs\pkey下有秘钥生成的代码,作为客户端,需要验证服务器提供的公钥证书,因此本地还要CA证书,类似首次登录12306提示要下载的证书,再加上客户端自身的公钥和私钥,一共3个文件。gen_key.c生成keyfile.key私钥,默认秘钥长度是4096,虽然1024理论上有风险,但是运算更快;后面再使用openSSL 命令行生成公钥。

  OpenSSL> rsa -in private.key -pubout -out public.key

  openSSL下载地址https://www.openssl.org/,安装后提示使用收费,实际使用未见异常。秘钥也可使用openSSL生成

  OpenSSL>genrsa -out private.key 2048

  如果使用未知,使用help查看说明。至于CA证书,需要平台侧生成再提供给设备端。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表