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


原创声明

本文为 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】
    在这里插入图片描述
  • 按步骤进行资料填写:
    在这里插入图片描述
  • 选择需要下载的版本,我这里选择了 4.4.0 版本
    在这里插入图片描述
  • 下拉到最后,点击 【Download】,会自动启动下载
    在这里插入图片描述

三、STM32 Cube 配置

3.1 Cube 配置

在这里插入图片描述
在这里插入图片描述

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

  • ① 将官方的文件里面的下图标红文件移动到项目文件里面
    在这里插入图片描述

  • ② 放到工程文件下:在这里插入图片描述
  • ③ 把wolfcrpt/srcsrc文件夹里面的文件加入到keil工程中
    在这里插入图片描述
  • ④ 工程加入必备头文件
    在这里插入图片描述
  • ⑤ 打开 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 includes. */
#include <wolfssl/ssl.h>
#include <wolfssl/internal.h>

/*!
* @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 证书
    在这里插入图片描述
  • ② 将板子插上网线,编译,烧录,连接 RTT ,可以看到打印信息
    在这里插入图片描述
  • ③ 这里作为演示项目,使用 Debug 模式,打上断点,可以看到拉取成功!!!
    在这里插入图片描述

总结

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


更多阅读推荐

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


授权须知

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值