David Dong

David Dong

Java/C/C#/Python

Java/C/C#/Python

POST

mbedtls 使用说明

最近的工作中使用到了mbedtls,这里做一个简单的总结。

1. 什么是 mbedtls

mbedtls 一句话来概况的话就是它是一个开源的SSL/TLS库。
–项目源码地址
–项目API文档

1.1 SSL

关于SSL(Secure Sockets Layer 安全套接字协议),百度百科的解释如下:

SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层:

  • SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
  • SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

TLS与SSL在传输层与应用层之间对网络连接进行加密。

1.2 mbedtls 特点

mbedtls 有以下的特点:

  • 简洁的API
  • 开源代码库
  • 功能模块化,松耦合。
  • 模块可单独配置,编译
  • C 语言编写,针对嵌入式应用

从功能角度来看,mbedtls可以分为三个主要部分:

  • SSL/TLS 协议库(libmbedtls.a
  • 加密库(libmbedcrypto.a
  • X.509 证书处理库(libmbedx509.a

注意:这三个库在生成的时候的依赖关系,libmbedtls.a 依赖 libmbedx509.a 而 libmbedx509.a 依赖 libmbedcrypto.a。 因此在生成时要注意顺序问题。

1.3 mbedtls 模块

mbedtls库包含以下的模块。

模块 说明
Encryption/decryption module 加解密模块
Hashing module The Message Digest (MD)提供了hash 功能
Random number generator (RNG) module 提供了随机数产生功能,see mbedtls_ctr_drbg_random()
SSL/TLS communication module 提供了方式建立SSL/TLS通讯通道
TCP/IP communication module provides for a channel of communication for the SSL/TLS communication module to use
X.509 module 提供了X.509的支持,用于证书的读写和认证
Asn1_module  

2. mbedtls 安装与配置

mbedtls支持3种 build 方式,

  • GNU Make
  • CMake
  • Microsoft Visual Studio (Microsoft Visual Studio 2013 or later)

2.1 工具链支持

  • GNU Make 或者 CMake build 工具.
  • C99 工具链 (compiler, linker, achiever). 目前支持 GCC5.4, Clang 3.8, IAR8Visual Studio 2013 以后的版本.
  • Python 3 用于产生测试代码.
  • Perl 用于运行测试.

2.2 GNU Make

run build

make

build with test

make check

build without test

make no_test

2.3 CMake

run build

mkdir /path/to/build_dir && cd /path/to/build_dir
cmake /path/to/mbedtls_source
cmake --build .

run test

ctest

build without test

cmake -DENABLE_TESTING=Off /path/to/mbedtls_source

make shared library

cmake -DUSE_SHARED_MBEDTLS_LIBRARY=On /path/to/mbedtls_source

2.4 Microsoft Visual Studio

工程文件mbedTLS.sln 包含了所有必需的项目和程序. 编译该工程文件可以生成库文件。

关于更多的相关信息,可以参阅 GitHub README for Mbed TLS

3. mbedtls 使用

mbedtls通过提供以下功能支持SSLv3TLSv1.2版本的通信:

  • TCP/IP通信功能:监听、连接、接受、读/写
  • SSL/TLS通信功能:初始化、握手、读/写
  • X.509功能:CRT、CRL和按键处理
  • 随机数生成
  • 散列
  • 加密/解密

上面的功能被整齐地设计成逻辑接口。它们可以单独用于提供上述任何功能,或者混合和匹配到使用X.509 PKI的SSL服务器/客户端解决方案中。

3.1 例子

服务器端的设定:
先决条件

  • X.509证书和私钥
  • 会话处理函数 设定步骤
  • 加载证书和私钥(X.509接口)
  • 设置侦听TCP套接字(TCP/IP接口)
  • 接受传入客户端连接(TCP/IP接口)
  • 初始化为SSL服务器(SSL/TLS接口)
  • 设置参数,例如身份验证、密码、CA链、密钥交换
  • 设置回调函数RNG、IO、会话处理
  • 执行SSL握手(SSL/TLS接口)
  • 读/写数据(SSL/TLS接口)
  • 关闭和清理(所有接口)

客户端的设定:
先决条件

  • X.509证书和私钥
  • X.509可信CA证书 设定步骤
  • 加载受信任的CA证书(X.509接口)
  • 加载证书和私钥(X.509接口)
  • 设置TCP/IP连接(TCP/IP接口)
  • 初始化为SSL客户端(SSL/TLS接口)
  • 设置参数,例如身份验证模式、密码、CA链、会话
  • 设置回调函数RNG,IO
  • 执行SSL握手(SSL/TLS接口)
  • 验证服务器证书(SSL/TLS接口)
  • 写入/读取数据(SSL/TLS接口)
  • 关闭和清理(所有接口)

3.2 SSL/TLS 部分功能

mbed tls的ssl/tls部分提供了使用ssl/tls通过安全通信通道建立和通信方法。

其基本规定是:

  • 初始化一个SSL/TLS context
  • 执行一个SSL/TLS握手(handshake)
  • 发送/接收数据
  • 通知对方一个连接正在关闭

一个通道很多方面都是通过参数和回调函数来设置的 »>

  • 端点角色(endpoint role),客户端和服务器
  • 身份验证模式: 是否应该进行证书验证
  • 主机到主机通信通道: 发送和接收功能
  • 随机数生成器(RNG)功能
  • 用于加密/解密的密码
  • 证书验证功能
  • 会话控制: 会话获取和设置功能
  • 证书处理和密钥交换的X.509参数

mbed 通过创建一个SSL/TLS服务器和客户端,通过提供一个框架来建立和通过SSL/TLS通信通道进行通信.SSL/TLS部分直接依赖于库的证书解析,对称和非对称和哈希模块.

3.3 数据结构

mbedtls_net_context:目前只有文件描述符,可以用于适配异步I/O库
mbedtls_ssl_context:保存SSL基本数据
mbedtls_ssl_config: SSL 配置数据
mbedtls_ctr_drbg_context
mbedtls_entropy_context:保存熵配置
mbedtls_x509_crt:保存认证信息

3.4 Init 阶段

下面时init阶段需要调用的函数与传统 socket 的对比。传统的socket-based的程序,依照顺序,作为client要做以下的函数调用:

gethostbyname()
socket()
connect()
write()
read()

改成SSL之后,mbedTLS对应上述函数,分别对应为:

gethostbyname()   \ 
socket()          -+--> mbedtls_net_connect() + mbedtls_ssl_handshake()
connect()         /
write()           ----> mbedtls_ssl_write()
read()            ----> mbedtls_ssl_read()

当然,实际情况下,会使用更多的其他函数。

下面是init阶段需要调用的各函数。函数的参数,在调用的时候按照上面的函数类型一个一个传入就行了。

mbedtls_net_init()
mbedtld_ssl_init()
mbedtld_ssl_config_init()
mbedtls_ctr_drbg_init()
mbedtld_x509_crt_init()
mbedtls_entropy_init()
mebdtls_ctr_drbg_seed()

其中mebdtls_ctr_drbg_seed()可以指定熵函数。如果回调使用默认的mbedtls_entropy_func的话,可以传入一个初始的熵seed,也可以NULL。

3.5 Connect 阶段

mbedtls_net_connect():参数是server和端口,均为字符串。server可以使域名或者IP字符串。最后一个参数使用MBEDTLS_NET_PROTO_TCP即可。端口号不仅仅可以传入数字字符串,也可以类似于get_addrinfo函数的protocol参数那样,传入类似于HTTPS这样的可读化字符串。


Security

相关文章

继续阅读