You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过BearSSL将RSA公钥传输至同型号客户端开发板?

问题描述

两块集成BearSSL的同型号开发板,已通过br_rsa_i15_keygen生成RSA密钥对,需要将公钥传输到另一块开发板。最初的传输代码直接读取br_rsa_public_key的n数组转换为char后发送,但传输失败。添加调试代码后发现,n数组的数据会持续变化,猜测是BearSSL的时序攻击防护导致。

最初的传输代码:

bool trans_pk(WiFiClient &client, br_rsa_public_key &t_pk)
{
    char t_pkn[t_pk.nlen] = {0};
    for (int i = 0; i < t_pk.nlen; i++)
    {
        t_pkn[i] = (char)t_pk.n[i];
    }

    // Socket传输函数
    // transfer_sock(WiFiClient &client, const char *data, uint8_t dsize)
    transfer_sock(client, t_pkn, t_pk.nlen);

    // e部分的代码和n部分一致,仅变量名不同
    return true;
}

调试代码(发现n数组数据变化):

for (int i = 0; i < t_pk.nlen; i++)
{
    Serial.printf("%02x ", t_pk.n[i]);
}
Serial.printf("\n");

delay(1000);

for (int i = 0; i < t_pk.nlen; i++)
{
    Serial.printf("%02x ", t_pk.n[i]);
}
Serial.printf("\n");

解决方案

问题根源

你看到的n数组变化是正常现象:br_rsa_i15_keygen生成的是蒙哥马利形式的RSA公钥,BearSSL为了防范时序攻击,会对该公钥结构中的n做动态盲化(每次操作前后添加/移除随机小偏移),所以直接读取内存中的n数组会得到变化的值,但这不是真正的公钥模数。

正确的传输步骤

需要先将蒙哥马利形式的公钥转换为标准RSA公钥格式,得到固定的n(模数)和e(公钥指数),再进行传输:

  1. 转换公钥格式
    使用BearSSL提供的br_rsa_i15_pub_to_rsa函数,将蒙哥马利公钥转换为标准RSA公钥:
#include <bearssl_rsa.h>

bool trans_pk(WiFiClient &client, br_rsa_i15_public_key &t_pk)
{
    // 定义标准RSA公钥结构,分配存储n和e的缓冲区
    br_rsa_public_key standard_pk;
    uint8_t n_buf[BR_RSA_I15_MAX_NLEN]; // 根据你的密钥长度调整,比如2048位密钥对应256字节
    uint8_t e_buf[4]; // 公钥指数e通常是65537,占4字节

    // 初始化标准公钥结构
    standard_pk.n = n_buf;
    standard_pk.nlen = t_pk.nlen;
    standard_pk.e = e_buf;

    // 执行格式转换,返回e的长度
    standard_pk.elen = br_rsa_i15_pub_to_rsa(&t_pk, &standard_pk);
    if (standard_pk.elen == 0) {
        // 转换失败,处理错误
        return false;
    }

    // 直接传输标准公钥的n(无需转char,强制类型转换即可)
    transfer_sock(client, (const char*)standard_pk.n, standard_pk.nlen);
    // 传输标准公钥的e
    transfer_sock(client, (const char*)standard_pk.e, standard_pk.elen);

    return true;
}
  1. 接收方处理
    接收方收到n和e的字节后,组装成br_rsa_public_key结构即可使用;如果需要转换为蒙哥马利形式以适配BearSSL的快速运算接口,可以调用br_rsa_i15_pub_from_rsa函数完成转换。

额外注意事项

  • 避免使用char存储公钥字节:char可能是有符号类型,会导致0x80及以上的字节被错误转换,直接使用uint8_t数组或强制转换为const char*传输即可。
  • BearSSL的大整数采用大端字节序,传输和接收时保持字节顺序一致即可,无需额外调整。

内容的提问来源于stack exchange,提问作者ysPan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:05:34