如何芯片上运行完整的HTTPS服务器
TLS 1.2 HTTPS 服务器运行在单个芯片上——W55RP20(RP2040 + W5500)——您只需通过浏览器点击电路板的引脚图,即可实时控制 GPIO、PWM、ADC、I2C 和 SPI。无需云服务、网关或配套应用程序。
始于一个简单的问题
我有一个已经内置以太网的2美元筹码,能否直接通过浏览器(无需云服务)使用HTTPS连接该板?
通过嵌入式方式在网页上控制设备的常规方法如下:设备 → 网关 → 云端(MQTT/REST)→ 移动应用。中间需要经过多个跳转,你必须提前配置账户,一旦网络中断,甚至连放在自己桌上的控制面板都无法操作。
我想切断整个链路。设备会变成自己的服务器,同一网络中的浏览器直接连接到 https:/// 来切换钉子。网络内不产生任何数据,也不依赖任何外部服务。
麻烦从你坚持使用 HTTPS 而不是普通 HTTP 的那一刻就开始了。
W55RP20是什么?
W55RP20 是一款 WIZnet 芯片,将树莓派 RP2040(双核 Arm Cortex-M0+,264 KB SRAM)和 WIZnet 的硬连线 TCP/IP 以太网控制器 W5500 集成于一个封装中(SiP)。
W5500 是关键所在。通常,要在微控制器上实现以太网,需要运行像 lwIP 这样的软件 TCP/IP 栈。而 W5500 则通过芯片内部的硬件逻辑直接处理 TCP/UDP/IP/以太网(即硬连线的 TCP/IP)。微控制器只需通过 SPI 与套接字进行数据读写即可。这样一来,代码变得简单,也避免了软件栈所消耗的内存和计算负担——这对于内存受限的 TLS 工作负载尤为重要。
由于两者都集成在同一个芯片上,MCU + 以太网 + 安全Web服务器可以有效整合为一个部件。因此,该项目可宣称“一颗约2美元的芯片”。
我使用的开发板:W55RP20-EVB-Pico
固件实际上运行在WIZnet的评估板W55RP20-EVB-Pico上。它将W55RP20封装成树莓派Pico的外形,同时加装了一个RJ45以太网接口,因此你只需通过USB刷入固件,插入网线,即可接入网络,无需额外的以太网PHY或模块进行布线。
我所创造的
运行在 W55RP20-EVB-Pico 上的受登录保护的 HTTPS 服务器。连接后,板子的引脚布局将以 SVG 格式显示;点击某个引脚,即可选择其用途。
•交互式引脚布局界面——点击电路板图上的引脚,即可打开配置面板。输入和ADC值会自动刷新,因此引脚映射同时作为实时状态显示。
单针外设
•数字输入(上拉/下拉)/ 输出(高电平·低电平)
•PWM(频率 + 脉宽)
•ADC(原始值 + 电压 + 条形图),GP26–28
•I2C(总线扫描/寄存器读写)
•SPI(十六进制传输)
•可控制引脚:GP0–GP15,GP26–GP28
•登录认证——密码以SHA-256哈希形式存储在闪存中,会话Cookie(HttpOnly + Secure + SameSite),30分钟超时,最多支持5个账户
将 GPIO2 设置为输出,然后更改其值。
难点在于:如何让TLS在2美元的MCU上真正可用
将 mbedTLS 部署到 RP2040 上,编写一个简单的 HTTPS 服务器,结果它确实能运行。只是速度太慢,不适合实际使用。
问题出在握手过程上。浏览器默认使用如ECDHE-RSA之类的加密套件,但RP2040没有用于椭圆曲线(EC)运算的硬件加速器,所有计算都依赖软件完成。这导致每次握手需要数秒时间。试想一下,每次打开页面或点击按钮时都要等待几秒钟——这甚至都不够演示效果。
所以我以三种方式削减了握手成本。
1. 静态RSA加密套件仅限
我将服务器可协商的加密套件限制为TLS_RSA_WITH_AES_128_GCM_SHA256家族。通过完全取消EC密钥交换,我移除了最昂贵的项目——软件EC数学运算。
2. HTTP keep-alive
尽管如此,首次握手仍需要约2.2秒。这实际上就是200 MHz下软件RSA-2048的最低性能要求。因此,我只支付一次首次连接的费用,之后便重复使用该连接。此后每次页面加载、按钮切换或状态查询都通过同一连接进行,无需重新握手,体验速度因此发生显著变化。
3. 调整TLS记录缓冲区:由于有三个套接字同时运行,内存资源紧张。我将TLS记录缓冲区设置为输入2 KB / 输出8 KB,这样可以保持响应在几个记录之内,同时节省内存。
简单来说:问题不在于“MCU上的HTTPS运行缓慢”,而在于“简单的实现方式太慢”。通过控制协商过程并重用连接,即使在2美元的芯片上也能实现可用的HTTPS。
实际体验是这样的:首次连接时会有大约2秒的延迟(即握手过程),之后页面切换、钉子操作等一切操作都会立即响应。用户唯一感受到的慢速,就是一开始那一瞬间。
下一步:我正在考虑添加一个ECDSA P-256证书,以将首次握手时间从约2.2秒缩短到几百毫秒。
工作原理
网页文件以普通 board.html 格式编写,然后通过 CMake 构建步骤将其转换为 C 字节数组(board_page.h),并编译进固件中。换句话说,没有文件系统——该页面本身就是固件的一部分。
固件运行在FreeRTOS上,通过三个W5500套接字(最多可同时处理三个连接)驱动HTTPS服务器。
页面与首次登录
服务器根据用途被划分为若干个页面(路由)。
如何创建第一个登录ID?
刚刷新的板子没有任何注册账户,因此首次连接流程如下:
•当你第一次进入论坛(/)时,没有账户,因此会跳转到 /setup(首次创建账户)。
•在那里,您可以自行设置第一个管理员账户的ID和密码。
•为了防止任何人随意创建账户,您还需要输入一个创建密码。演示版本的默认密码是 w55rp20,实际使用时必须更改(请参见下方的安全部分)。
•账户创建后,使用该ID/密码登录 /login,之后即可通过 / 板块进行管理。
•在运行过程中添加或删除账户请使用 /account(最多5个)。
•您输入的密码会立即通过 SHA-256 哈希并存储在闪存中;明文永远不会被保存在任何地方。
安全能延伸多远
这是一个演示,但我并不想让它以玩具的形式结束,所以基础部分已经准备就绪。
•密码永远不会以明文形式存储,而是以SHA-256哈希值的形式保存在闪存中。
•会话 Cookie 使用 HttpOnly + Secure + SameSite,并设置 30 分钟的超时时间
创建账户需要单独设置一个密码(演示默认为 w55rp20)。要更改该密码,只需编辑 httpsAuth.h 文件中的单个字符串 HTTPS_CREATION_PASSWORD,然后重新编译即可。该密码在运行时通过 SHA-256 哈希生成,因此不存在预先计算好的哈希值可供替换。
坦率地说,当前版本使用的是自签名的演示证书,因此首次访问时浏览器会显示安全警告(这是正常现象)。私钥永远不会被提交。实际使用时,你需要自行生成并嵌入自己的证书和密钥;具体操作方法请参见 cert_work/README.md。
这是一个开发项目,因此部分功能可能不完整或不稳定。我不会直接将其部署在公开网络上。
亲测体验
这是一个 Raspberry Pi Pico SDK(CMake)项目。
Bash
将生成的 UF2/ELF 文件烧录到 W55RP20-EVB-Pico 上,连接以太网,然后在浏览器中打开 HYPERLINK "https://。"
所用物品
硬件
•W55RP20-EVB-Pico(RP2040 + W5500 单芯片)
•以太网连接
•任何您想要驱动的 I2C/SPI 外设(可选)
软件 / 框架
•Raspberry Pi Pico SDK(CMake)
•FreeRTOS
•mbedTLS(TLS 1.2)
•WIZnet ioLibrary
从这里可以发展出什么
由于该项目是“基于W55RP20的可靠网络+PIN控制”的基础,因此其结构框架在多个方向上延伸。
•传感器网关——无需控制引脚,而是读取温度、湿度、电流等传感器数据,并通过网络或Web接口传输出去。(工作计划草案 SENSOR_GATEWAY_WORK_PLAN.md 已存放在代码仓库中。)
•SNMP代理——将SNMP集成到同一板卡上,标准的网络管理系统(NMS)即可直接监控该设备。(仓库包含SNMP_AGENT_WORK_PLAN.md文件以及ioLibrary的SNMP补丁。)
•工业远程I/O面板——通过内部网络浏览器安全地检查和控制现场设备的数字/模拟I/O(HTTPS + 登录)。
•S2E 配置 Web 界面 — 通过相同的安全 Web 接口暴露串行转以太网转换器的设置。
关键在于:先一次性构建好TLS优化和认证框架,然后你再添加的任何内容都可以直接复用。
总结
如果这个项目要说明一点,那就是:一个“完整的HTTPS服务器”已不再局限于树莓派级别的Linux板。即使使用的是价格约2美元、带有集成以太网的微控制器,只要做出几个决定——控制协商过程并重用连接——就能获得一个可用且安全的Web界面。而无需任何云服务代码。
接下来是:使用ECDSA证书缩短首次握手,并添加更多外围类型。
本文编译自hackster.io





