文章目录
- 前言
- 一、HTTPS 工作流程简单介绍
- 二、WolfSSL 简单介绍
- 2.1 WolfSSL 是什么?
- 2.2 获取官方 SDK
- 三、STM32 Cube 配置
- 3.1 Cube 配置
- 3.2 修改 PHY 地址
- 四、生成工程的简单测试
- 4.1 手动修改 MAC 地址
- 4.2 Ping 测试
- 五、使用 Lwip + WolfSSL 实现 HTTPs
- 5.1 引入库
- 5.2 开启打印 Log 信息
- 5.3 HTTPs 拉取 baidu.com
- 总结
前言
如今的物联网时代,需要追求数据通信的安全性,传统的 HTTP 是明文传输,需要使用 HTTPS 的加密机制才能有效保证传输数据的安全性,WolfSSL 是一个轻量级的 SSL / TLS 库 ,能够很好的使用在嵌入式设备上面。
码字不易,如果帮到您,请帮我在屏幕下方点赞 ,您的点赞可以让技术传播得更远更广,谢谢!
一、HTTPS 工作流程简单介绍
下图是一个简单版本的 https 通讯过程,这里不详细讲解了
客户端 服务器 ① Client Hello ② Server Hello ③ 公钥加密 ④ 对称密钥加密(对称密钥加密) ⑤ 请求内容(对称密钥加密) ⑥ 相应内容(对称密钥加密) 客户端 服务器二、WolfSSL 简单介绍
2.1 WolfSSL 是什么?
WolfSSL 嵌入式 SSL库
是用 ANSI C
编写的轻量级 SSL / TLS 库,主要针对嵌入式,RTOS 和资源受限的环境——主要是因为其体积小,速度快和功能集丰富。由于其免版税定价和出色的跨平台支持,它也通常用于标准操作环境。wolfSSL支持高达当前 TLS 1.3 和 DTLS 1.2 级别的行业标准,比 OpenSSL 小多达20倍,并提供诸如 ChaCha20,Curve25519,NTRU 和 Blake2b 之类的渐进密码。在通过OpenSSL 使用 wolfSSL 时,用户基准测试和反馈报告可显着提高性能。
2.2 获取官方 SDK
WolfSSL官网
- 点击【Download Now】
- 按步骤进行资料填写:
- 选择需要下载的版本,我这里选择了 4.4.0 版本
- 下拉到最后,点击 【Download】,会自动启动下载
三、STM32 Cube 配置
3.1 Cube 配置
3.2 修改 PHY 地址
本项目使用的是 LAN8720
芯片,需要修改 PHY Address
为 0
四、生成工程的简单测试
4.1 手动修改 MAC 地址
Cube 生成的 MAC
地址是固定的,防止和测试环境中的其他设备相撞,需要打开文件 ethernetif.c
手动修改 MAC
地址,我这里提取了 芯片ID
作为MAC
地址的最后几位,这里是 STM32F767
的芯片ID的地址 0x1FF0F420
uint32_t sn0 = *(uint32_t *)(0x1FF0F420);//STM32 cpu id
MACAddr[3] = (sn0 >> 16) & 0xFF;
MACAddr[4] = (sn0 >> 8) & 0xFFF;
MACAddr[5] = sn0 & 0xFF;
4.2 Ping 测试
编译 -> 烧录 到单片机里面,拿一条和 PC 在同一局域网内的网线,根据 MX_LWIP_Init()
函数下面设置的 IP
测试 ping
功能,下面是成功的结果图:
五、使用 Lwip + WolfSSL 实现 HTTPs
5.1 引入库
- ① 将官方的文件里面的下图标红文件移动到项目文件里面
- ② 放到工程文件下:
- ③ 把
wolfcrpt/src
,src
文件夹里面的文件加入到keil工程中
- ④ 工程加入必备头文件
- ⑤ 打开
wolfssl\wolfcrypt\setting.h
文件,加入宏定义
#define WOLFSSL_USER_SETTINGS //使用自定义配置
- ⑥ 在
WolfSSL
文件夹下加入一个文件user_settings.h
,下面是 STM32F7 的例子,请根据实际情况设置!!!
#ifndef WOLFSSL_USER_SETTINGS_H
#define WOLFSSL_USER_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
#undef WOLFSSL_GENERAL_ALIGNMENT
#define WOLFSSL_GENERAL_ALIGNMENT 4
#undef SINGLE_THREADED
#define SINGLE_THREADED
#undef WOLFSSL_SMALL_STACK
#define WOLFSSL_SMALL_STACK
#undef WOLFSSL_STM32F7
#define WOLFSSL_STM32F7
#undef WOLFSSL_STM32_CUBEMX
#define WOLFSSL_STM32_CUBEMX
#define NO_STM32_HASH
//#define NO_STM32_RNG
#define NO_STM32_CRYPTO
#undef FREERTOS
#define FREERTOS
#undef WOLFSSL_LWIP
#define WOLFSSL_LWIP
//#define HAVE_LWIP_NATIVE
#undef USE_FAST_MATH
#define USE_FAST_MATH
#ifdef USE_FAST_MATH
#undef TFM_TIMING_RESISTANT
#define TFM_TIMING_RESISTANT
#undef TFM_NO_ASM
//#define TFM_NO_ASM
//#define TFM_ASM
#endif
#if 1
#undef HAVE_ECC
#define HAVE_ECC
#undef ECC_USER_CURVES
#define ECC_USER_CURVES
//#define HAVE_ECC192
//#define HAVE_ECC224
#undef NO_ECC256
//#define HAVE_ECC384
//#define HAVE_ECC521
#undef FP_ECC
//#define FP_ECC
#ifdef FP_ECC
#undef FP_ENTRIES
#define FP_ENTRIES 2
#undef FP_LUT
#define FP_LUT 4
#endif
#undef ECC_SHAMIR
#define ECC_SHAMIR
#undef ECC_TIMING_RESISTANT
#define ECC_TIMING_RESISTANT
#ifdef USE_FAST_MATH
#undef ALT_ECC_SIZE
#define ALT_ECC_SIZE
//#undef FP_MAX_BITS_ECC
//#define FP_MAX_BITS_ECC 512
//#define TFM_ECC192
//#define TFM_ECC224
//#define TFM_ECC256
//#define TFM_ECC384
//#define TFM_ECC521
#endif
#endif
#undef NO_RSA
#if 1
#ifdef USE_FAST_MATH
#undef FP_MAX_BITS
#define FP_MAX_BITS 4096
#endif
#undef RSA_LOW_MEM
//#define RSA_LOW_MEM
#undef WC_RSA_BLINDING
#define WC_RSA_BLINDING
#else
#define NO_RSA
#endif
#undef NO_AES
#if 1
#undef HAVE_AESGCM
#define HAVE_AESGCM
#ifdef HAVE_AESGCM
#undef WOLFSSL_AES_COUNTER
#define WOLFSSL_AES_COUNTER
#undef WOLFSSL_AES_DIRECT
#define WOLFSSL_AES_DIRECT
#endif
#undef GCM_SMALL
#define GCM_SMALL
#else
#define NO_AES
#endif
#undef HAVE_CHACHA
#undef HAVE_POLY1305
#if 0
#define HAVE_CHACHA
#define HAVE_POLY1305
#undef HAVE_ONE_TIME_AUTH
#define HAVE_ONE_TIME_AUTH
#endif
#undef HAVE_CURVE25519
#undef HAVE_ED25519
#if 0
#define HAVE_CURVE25519
#define HAVE_ED25519
#if 0
#define CURVED25519_SMALL
#endif
#endif
#undef NO_SHA
#if 1
//#define USE_SLOW_SHA
#else
#define NO_SHA
#endif
#undef NO_SHA256
#if 1
#if 1
#define WOLFSSL_SHA224
#endif
#else
#define NO_SHA256
#endif
#undef WOLFSSL_SHA512
#if 1
#define WOLFSSL_SHA512
#undef WOLFSSL_SHA384
#if 1
#define WOLFSSL_SHA384
#endif
//#define USE_SLOW_SHA2
#endif
// #undef NO_MD5
// #if 1
//
// #else
// #define NO_MD5
// #endif
// See settings.h STM32F4 section
//#undef BENCH_EMBEDDED
//#define BENCH_EMBEDDED
//#undef USE_CERT_BUFFERS_2048
//#define USE_CERT_BUFFERS_2048
//#undef USE_CERT_BUFFERS_256
//#define USE_CERT_BUFFERS_256
#undef WOLFSSL_DEBUG
#define WOLFSSL_DEBUG
#ifdef WOLFSSL_DEBUG
#if 0
#undef USE_WOLFSSL_MEMORY
#define USE_WOLFSSL_MEMORY
#undef WOLFSSL_TRACK_MEMORY
#define WOLFSSL_TRACK_MEMORY
#endif
#else
// #undef NO_WOLFSSL_MEMORY
// #define NO_WOLFSSL_MEMORY
#undef NO_ERROR_STRINGS
//#define NO_ERROR_STRINGS
#endif
#ifdef DEBUG_WOLFSSL
#undef WOLFSSL_DEBUG_ERRORS_ONLY
#include "dbg_tools.h"
#define WOLFSSL_USER_LOG(x) do { DbgPrint(x); DbgPrint("\n"); } while(0);
#endif
#define WOLFSSL_USER_CURRTIME
#define CUSTOM_RAND_TYPE unsigned int
#define NO_OLD_RNGNAME
#if 1
#undef HAVE_HASHDRBG
#define HAVE_HASHDRBG
#if 0
extern unsigned int custom_rand_generate(void);
#undef CUSTOM_RAND_GENERATE
#define CUSTOM_RAND_GENERATE custom_rand_generate
#endif
#else
extern int custom_rand_generate_block(unsigned char* output, unsigned int sz);
#undef CUSTOM_RAND_GENERATE_BLOCK
#define CUSTOM_RAND_GENERATE_BLOCK custom_rand_generate_block
#endif
#undef KEEP_PEER_CERT
//#define KEEP_PEER_CERT
#undef HAVE_COMP_KEY
//#define HAVE_COMP_KEY
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef HAVE_SUPPORTED_CURVES
#define HAVE_SUPPORTED_CURVES
#undef WOLFSSL_BASE64_ENCODE
#define WOLFSSL_BASE64_ENCODE
#if 0
#define SMALL_SESSION_CACHE
#else
#define NO_SESSION_CACHE
#endif
#undef USER_TIME
#define USER_TIME //需要在应用层定义自己的 time_t XTIME(time_t * timer) 函数,直接定义即可
//#undef NO_WOLFSSL_SERVER
#define NO_WOLFSSL_SERVER
//#undef NO_WOLFSSL_CLIENT
#define NO_WOLFSSL_CLIENT
//#undef NO_CRYPT_TEST
#define NO_CRYPT_TEST
//#undef NO_CRYPT_BENCHMARK
#define NO_CRYPT_BENCHMARK
//
//
//
//#undef NO_INLINE
#define NO_INLINE
//#undef NO_FILESYSTEM
//#define NO_FILESYSTEM
//#undef NO_WRITEV
//#define NO_WRITEV
//#undef NO_MAIN_DRIVER
//#define NO_MAIN_DRIVER
#undef NO_DEV_RANDOM
#define NO_DEV_RANDOM
//#undef NO_DSA
//#define NO_DSA
//#undef NO_DH
//#define NO_DH
//#undef NO_DES3
//#define NO_DES3
//#undef NO_RC4
//#define NO_RC4
//#undef NO_OLD_TLS
//#define NO_OLD_TLS
//#undef NO_HC128
//#define NO_HC128
//#undef NO_RABBIT
//#define NO_RABBIT
//#undef NO_PSK
//#define NO_PSK
//#undef NO_MD4
//#define NO_MD4
//#undef NO_PWDBASED
//#define NO_PWDBASED
#ifdef __cplusplus
}
#endif
#endif
- ⑦ 在应用代码里面加入
wolfssl
获取时间戳的函数,这里使用的是SNTP
获取网络时间存入RTC
,然后使用接口从RTC
获取时间,关于如何使用LWIP+SNTP
获取实时网络时间请看我这篇教程: 【嵌入式实战】STM32+Lwip 实现 SNTP 网络授时(超详细)
#include <wolfssl/ssl.h>
#include <wolfssl/internal.h>
time_t XTIME(time_t * timer)
{
time_t timestamp = get_timestamp(); // 没有实现 SNTP 的话,先使用网上获取的最新时间的时间戳,例如:1595836376
return timestamp;
}
5.2 开启打印 Log 信息
在 user_setting.h
中定义宏定义
//开启 wolfssl 的log输出
#define DEBUG_WOLFSSL
#ifdef DEBUG_WOLFSSL
#undef WOLFSSL_DEBUG_ERRORS_ONLY
#include "bsp_printlog.h"
#define WOLFSSL_USER_LOG(x) do { print_log(x); print_log("\n"); } while(0); //需要自己实现 print_log 函数
#endif
在 WlofSSL程序开始之前,加入函数接口
wolfSSL_Debugging_ON();
5.3 HTTPs 拉取 baidu.com
- ① 获取网站的
HTTPS
的pem
证书
- ② 将板子插上网线,编译,烧录,连接 RTT ,可以看到打印信息
- ③ 这里作为演示项目,使用
Debug
模式,打上断点,可以看到拉取成功!!!
总结
以上是 STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS
的全部内容。项目文件已经上传到 GitHub :STM32_HTTPs_WolfSSL ,项目除了上述内容外,另外还实现了 DHCP、SNTP、netbios 功能 ,如果有帮助请大家帮忙点个 star ,谢谢!!!
码字不易,如果这篇教程帮到您,请帮我在屏幕下方点赞 ,您的点赞可以让技术传播得更远更广,谢谢!