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

   日期:2020-09-01     浏览:147    评论:0    
核心提示:文章目录前言一、HTTPS 工作流程简单介绍二、WolfSSL 简单介绍2.1 WolfSSL 是什么?2.2 获取官方 SDK三、STM32 Cube 配置3.1 Cube 配置3.2 修改 PHY 地址四、生成工程的简单测试4.1 手动修改 MAC 地址4.2 Ping 测试五、使用 Lwip + WolfSSL 实现 HTTPs5.1 引入库5.2 开启打印 Log 信息5.3 HTTPs 拉取 baidu.com总结.前言如今的物联网时代,需要追求数据通信的安全性,传统的 HTTP 是明文传

文章目录

  • 前言
  • 一、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 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 的例子,请根据实际情况设置!!!
 

#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

  • ① 获取网站的 HTTPSpem 证书
  • ② 将板子插上网线,编译,烧录,连接 RTT ,可以看到打印信息
  • ③ 这里作为演示项目,使用 Debug 模式,打上断点,可以看到拉取成功!!!

总结

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

码字不易,如果这篇教程帮到您,请帮我在屏幕下方点赞 ,您的点赞可以让技术传播得更远更广,谢谢!

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服