【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)

文章目录

  • 原创声明
  • 前言
  • 一、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
  • 总结
  • 授权须知


原创声明

本文为 HinGwenWoong 原创,如果这篇文章对您有帮助,欢迎转载,转载请阅读文末的【授权须知】,感谢您对 HinGwenWoong 文章的认可!


前言

如今的物联网时代,需要追求数据通信的安全性,传统的 HTTP 是明文传输,需要使用 HTTPS 的加密机制才能有效保证传输数据的安全性,WolfSSL 是一个轻量级的 SSL / TLS 库 ,能够很好的使用在嵌入式设备上面。

我是 HinGwenWoong ,一个有着清晰目标不停奋斗的程序猿,热爱技术,喜欢分享,码字不易,如果帮到您,请帮我在屏幕下方点赞 ,您的点赞可以让技术传播得更远更广,谢谢!


一、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】
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第1张图片
  • 按步骤进行资料填写:
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第2张图片
  • 选择需要下载的版本,我这里选择了 4.4.0 版本
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第3张图片
  • 下拉到最后,点击 【Download】,会自动启动下载
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第4张图片

三、STM32 Cube 配置

3.1 Cube 配置

【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第5张图片
【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第6张图片

3.2 修改 PHY 地址

本项目使用的是 LAN8720 芯片,需要修改 PHY Address0
在这里插入图片描述


四、生成工程的简单测试

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 引入库

  • ① 将官方的文件里面的下图标红文件移动到项目文件里面
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第7张图片

  • ② 放到工程文件下:【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第8张图片
  • ③ 把wolfcrpt/srcsrc文件夹里面的文件加入到keil工程中
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第9张图片
  • ④ 工程加入必备头文件
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第10张图片
  • ⑤ 打开 wolfssl\wolfcrypt\setting.h 文件,加入宏定义
#define WOLFSSL_USER_SETTINGS  //使用自定义配置
  • ⑥ 在 WolfSSL文件夹下加入一个文件 user_settings.h,下面是 STM32F7 的例子,请根据实际情况设置!!!
 /* Example wolfSSL user settings for STM32F7 with CubeMX */

#ifndef WOLFSSL_USER_SETTINGS_H
#define WOLFSSL_USER_SETTINGS_H

#ifdef __cplusplus
extern "C" {
     
#endif


/* ------------------------------------------------------------------------- */
/* Platform */
/* ------------------------------------------------------------------------- */
#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

/* Optionally Disable Hardware Hashing Support */
#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

/* ------------------------------------------------------------------------- */
/* Math Configuration */
/* ------------------------------------------------------------------------- */
#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

    /* Optimizations (TFM_ARM, TFM_ASM or none) */
    //#define TFM_ASM
#endif


/* ------------------------------------------------------------------------- */
/* Crypto */
/* ------------------------------------------------------------------------- */
/* ECC */
#if 1
    #undef  HAVE_ECC
    #define HAVE_ECC

    /* Manually define enabled curves */
    #undef  ECC_USER_CURVES
    #define ECC_USER_CURVES

    //#define HAVE_ECC192
    //#define HAVE_ECC224
    #undef NO_ECC256
    //#define HAVE_ECC384
    //#define HAVE_ECC521

    /* Fixed point cache (speeds repeated operations against same private key) */
    #undef  FP_ECC
    //#define FP_ECC
    #ifdef FP_ECC
        /* Bits / Entries */
        #undef  FP_ENTRIES
        #define FP_ENTRIES  2
        #undef  FP_LUT
        #define FP_LUT      4
    #endif

    /* Optional ECC calculation method */
    /* Note: doubles heap usage, but slightly faster */
    #undef  ECC_SHAMIR
    #define ECC_SHAMIR

    /* Reduces heap usage, but slower */
    #undef  ECC_TIMING_RESISTANT
    #define ECC_TIMING_RESISTANT

    #ifdef USE_FAST_MATH
        /* use reduced size math buffers for ecc points */
        #undef  ALT_ECC_SIZE
        #define ALT_ECC_SIZE

        /* optionally override the default max ecc bits */
        //#undef  FP_MAX_BITS_ECC
        //#define FP_MAX_BITS_ECC     512

        /* Enable TFM optimizations for ECC */
        //#define TFM_ECC192
        //#define TFM_ECC224
        //#define TFM_ECC256
        //#define TFM_ECC384
        //#define TFM_ECC521
    #endif
#endif

/* RSA */
#undef NO_RSA
#if 1
    #ifdef USE_FAST_MATH
        /* Maximum math bits (Max RSA key bits * 2) */
        #undef  FP_MAX_BITS
        #define FP_MAX_BITS     4096
    #endif

    /* half as much memory but twice as slow */
    #undef  RSA_LOW_MEM
    //#define RSA_LOW_MEM

    /* Enables blinding mode, to prevent timing attacks */
    #undef  WC_RSA_BLINDING
    #define WC_RSA_BLINDING

#else
    #define NO_RSA
#endif

/* AES */
#undef NO_AES
#if 1
    #undef  HAVE_AESGCM
    #define HAVE_AESGCM

    #ifdef HAVE_AESGCM
        /* GCM with hardware acceleration requires AES counter/direct for unaligned sizes */
        #undef  WOLFSSL_AES_COUNTER
        #define WOLFSSL_AES_COUNTER

        #undef  WOLFSSL_AES_DIRECT
        #define WOLFSSL_AES_DIRECT
    #endif

    /* GCM Method: GCM_SMALL, GCM_WORD32 or GCM_TABLE */
    #undef  GCM_SMALL
    #define GCM_SMALL
#else
    #define NO_AES
#endif

/* ChaCha20 / Poly1305 */
#undef HAVE_CHACHA
#undef HAVE_POLY1305
#if 0
    #define HAVE_CHACHA
    #define HAVE_POLY1305

    /* Needed for Poly1305 */
    #undef  HAVE_ONE_TIME_AUTH
    #define HAVE_ONE_TIME_AUTH
#endif

/* Ed25519 / Curve25519 */
#undef HAVE_CURVE25519
#undef HAVE_ED25519
#if 0
    #define HAVE_CURVE25519
    #define HAVE_ED25519

    /* Optionally use small math (less flash usage, but much slower) */
    #if 0
        #define CURVED25519_SMALL
    #endif
#endif


/* ------------------------------------------------------------------------- */
/* Hashing */
/* ------------------------------------------------------------------------- */
/* Sha */
#undef NO_SHA
#if 1
    /* 1k smaller, but 25% slower */
    //#define USE_SLOW_SHA
#else
    #define NO_SHA
#endif

/* Sha256 */
#undef NO_SHA256
#if 1
    #if 1
        #define WOLFSSL_SHA224
    #endif
#else
    #define NO_SHA256
#endif

/* Sha512 */
#undef WOLFSSL_SHA512
#if 1
    #define WOLFSSL_SHA512

    /* Sha384 */
    #undef  WOLFSSL_SHA384
    #if 1
        #define WOLFSSL_SHA384
    #endif

    /* over twice as small, but 50% slower */
    //#define USE_SLOW_SHA2
#endif

/* MD5 */
// #undef  NO_MD5
// #if 1
//    /* enabled */
// #else
//    #define NO_MD5
// #endif


/* ------------------------------------------------------------------------- */
/* HW Crypto Acceleration */
/* ------------------------------------------------------------------------- */
// See settings.h STM32F4 section


/* ------------------------------------------------------------------------- */
/* Benchmark / Test */
/* ------------------------------------------------------------------------- */
/* Use reduced benchmark / test sizes */
//#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


/* ------------------------------------------------------------------------- */
/* Debugging */
/* ------------------------------------------------------------------------- */
#undef  WOLFSSL_DEBUG
#define WOLFSSL_DEBUG

#ifdef WOLFSSL_DEBUG
    /* Use this to measure / print heap usage */
    #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

/* ------------------------------------------------------------------------- */
/* Port */
/* ------------------------------------------------------------------------- */

/* Override Current Time */
/* Allows custom "custom_time()" function to be used for benchmark */
#define WOLFSSL_USER_CURRTIME


/* ------------------------------------------------------------------------- */
/* RNG */
/* ------------------------------------------------------------------------- */
/* Size of returned HW RNG value */
#define CUSTOM_RAND_TYPE      unsigned int

#define NO_OLD_RNGNAME

/* Choose RNG method */
#if 1
    /* Use built-in P-RNG (SHA256 based) with HW RNG */
    /* P-RNG + HW RNG (P-RNG is ~8K) */
    #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
    /* Bypass P-RNG and use only HW RNG */
    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


/* ------------------------------------------------------------------------- */
/* Enable Features */
/* ------------------------------------------------------------------------- */
#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

/* TLS Session Cache */
#if 0
    #define SMALL_SESSION_CACHE
#else
    #define NO_SESSION_CACHE
#endif

#undef  USER_TIME
#define USER_TIME   //需要在应用层定义自己的 time_t XTIME(time_t * timer) 函数,直接定义即可

/* ------------------------------------------------------------------------- */
/* Disable Features */
/* ------------------------------------------------------------------------- */
//#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

///* In-lining of misc.c functions */
///* If defined, must include wolfcrypt/src/misc.c in build */
///* Slower, but about 1k smaller */
//#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_USER_SETTINGS_H */

  • ⑦ 在应用代码里面加入 wolfssl 获取时间戳的函数,这里使用的是 SNTP 获取网络时间存入 RTC,然后使用接口从 RTC 获取时间,关于如何使用 LWIP+SNTP 获取实时网络时间请看我这篇教程: 【嵌入式实战】STM32+Lwip 实现 SNTP 网络授时(超详细)
/* wolfssl includes. */
#include 
#include 

/*!
* @brief 重写 wolfssl 的时间获取函数
*        执行条件:无
*
* @retval: 返回时间戳
*/
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

  • ① 获取网站的 HTTPSpem 证书
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第11张图片
  • ② 将板子插上网线,编译,烧录,连接 RTT ,可以看到打印信息
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第12张图片
  • ③ 这里作为演示项目,使用 Debug 模式,打上断点,可以看到拉取成功!!!
    【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)_第13张图片

总结

以上是 STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS 的全部内容。项目文件已经上传到 GitHub :STM32_HTTPs_WolfSSL ,项目除了上述内容外,另外还实现了 DHCP、SNTP、netbios 功能 ,如果有帮助请大家帮忙点个 star ✨✨✨ ,谢谢!!!


更多阅读推荐
  • 【嵌入式实战】STM32+Lwip 实现 DHCP+HostName(超详细) : 在 DHCP 的基础上 Ping 域名的方式获取 DHCP 的 IP
  • 【嵌入式实战】STM32+Lwip 实现 SNTP 网络授时(超详细)
  • 【嵌入式小技巧】stm32 实现 Segger RTT 打印(超详细)

我是 HinGwenWoong ,一个有着清晰目标不停奋斗的程序猿,热爱技术,喜欢分享,码字不易,如果帮到您,请帮我在屏幕下方点赞 ,您的点赞可以让技术传播得更远更广,谢谢!


授权须知

  1. 原创文章在推送两天后才可进行转载
  2. 转载文章,禁止声明原创
  3. 不允许直接二次转载,转载请根据原文链接联系作者
  4. 若无需改版,在文首清楚标注作者及来源/原文链接,并删除【原创声明】,即可直接转载。
    但对于未注明转载来源/原文链接的文章,我将保留追述的权利。

作者:HinGwenWoong
一个有着清晰目标不停奋斗的程序猿,热爱技术,喜欢分享,共同进步!
CSDN: HinGwenWoong
原文链接:【嵌入式实战】STM32+FreeRTOS+LWIP+WolfSSL 实现 HTTPS(超详细)

  1. 若需要修改文章的排版,请根据原文链接联系作者
  2. 再次感谢您的认可,转载请遵守如上转载须知!

你可能感兴趣的:(嵌入式SMT32,嵌入式,stm32,https,ssl,物联网)