-1

我目前正在尝试将我的 ESP32 连接到 AWS IoT。因此,我必须使用证书来加密连接。理论上我知道这将如何工作,但我不是 C++ 专业人士,我得到了一个错误。当然,我尝试 google,但我总是找到对我不起作用的相同解决方案。具体来说,我尝试在头文件中声明一个 cacert,如下所示:

const char AWS_CERT_CA[] = "-----BEGIN CERTIFICATE-----\n" \
"MIIDQTChkiG9w0CAimfz5m/jAo5gAwIBBgkqBAkPmljZbyjQsAgITBmy4vB4iANF\n" \
"ADA5MGQW1hem5sGQW1hemDVVUzEMQxBBDVhMQsYDVQQQGEwJQDExBBbWF6\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"-----END CERTIFICATE-----\n";

在主文件中,我尝试像这样使用它:

WiFiClientSecure net = WiFiClientSecure();
void connectToAWS()
{
    // Configure WiFiClientSecure to use the AWS certificates we generated
    net.setCACert(AWS_CERT_CA);
    net.setCertificate(AWS_CERT_CRT);
    net.setPrivateKey(AWS_CERT_PRIVATE);
...

当我尝试编译时,它给了我以下错误:

在此处输入图像描述

显然,参数类型不正确,但为什么它对其他人有效(例如herehere)?一个 int 作为函数的参数对我来说没有意义。希望您能够帮助我。

4

2 回答 2

0

首先,请避免发布带有编译器输出的屏幕截图。相反,请复制输出文本并将其粘贴到您的帖子中(使用相关格式)。

您似乎正在使用具有不同接口的旧版本WiFiClientSecure 库setCACert()-需要两个参数,即密钥及其长度。你为什么不试试呢?

net.setCACert((const uint8_t*)AWS_CERT_CA, sizeof(AWS_CERT_CA) - 1);

剥离终止空值,因为该- 1函数似乎采用二进制 blob,而那些通常不带有终止符。如果身份验证不起作用,请尝试删除该减法。

于 2021-01-05T13:26:39.563 回答
0

所以我花了很长时间才弄清楚如何解决这个问题。主要问题是我使用的是旧版本的 BearSSL,但我无法更新它。为了避免这个问题,我使用我的加密信息创建文件,并使用这些文件创建与 AWS iot 的安全连接。此外,我不使用 MQTT 来传输我的指标,而是使用 REST 端点。我确信这不是一个最佳解决方案,但它到目前为止有效。这是我的做法。首先要了解的事情:

  • net 是 WiFiClientSecure 的一个实例: BearSSL::WiFiClientSecure net = BearSSL::WiFiClientSecure();

我的加密信息(密钥、CACert、证书)如下所示:

const char AWS_CA_CERT[]="-----BEGIN CERTIFICATE-----\n" \
...
"rqXRfboQnoZsG4q5WTP468SQvvG5\n" \
"-----END CERTIFICATE-----";

建立 Wifi 连接后,我执行以下操作来建立安全连接:

bool establishSecureConnection()
{
  if (!SPIFFS.begin())
  {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return false;
  }

  File tempCA = SPIFFS.open("/ca.crt", "w");
  File tempCert = SPIFFS.open("/cert.crt", "w");
  File tempKey = SPIFFS.open("/cert.priv", "w");

  if (!tempCA || !tempCert || !tempKey)
  {
    Serial.println("There was an error opening the file for writing");
    return false;
  }

  if (tempCA.print(AWS_CA_CERT))
  {
    Serial.println("Ca File was written");
  }
  else
  {
    Serial.println("Ca File write failed");
  }
  tempCA.close();

  if (tempCert.print(AWS_CERT))
  {
    Serial.println("cert File was written");
  }
  else
  {
    Serial.println("cert File write failed");
  }
  tempCert.close();

  if (tempKey.print(AWS_PRIVATE_KEY))
  {
    Serial.println("key File was written");
  }
  else
  {
    Serial.println("key File write failed");
  }
  tempKey.close();

  File ca = SPIFFS.open("/ca.crt", "r");
  if (!ca)
  {
    Serial.println("Failed to open ca file for reading");
    return false;
  }

  File cert = SPIFFS.open("/cert.crt", "r");
  if (!cert)
  {
    Serial.println("Failed to open cert file for reading");
    return false;
  }

  File pk = SPIFFS.open("/cert.priv", "r");
  if (!pk)
  {
    Serial.println("Failed to open pk file for reading");
    return false;
  }
  if (net.loadCACert(ca))
  {
    Serial.println("Successfully loaded ca");
  }
  else
  {
    Serial.println("Could not load ca");
    return false;
  }
  if (net.loadCertificate(cert))
  {
    Serial.println("Successfully loaded cert");
  }
  else
  {
    Serial.println("Could not load cert");
    return false;
  }
  if (net.loadPrivateKey(pk))
  {
    Serial.println("Successfully loaded pk");
  }
  else
  {
    Serial.println("Could not load pk");
    return false;
  }

  net.setTimeout(20000);
  if (!net.connect(AWS_IOT_ENDPOINT, 8443))
  {
    Serial.println("connection failed");
    char err_buf[1024];
    Serial.println(net.getLastSSLError(err_buf, 1024));
    Serial.printf("ssl_error: %s\n", err_buf);
    return false;
  }
  else
  {
    Serial.println("Connected to AWS!");
  }
  return true;
}
于 2021-02-03T13:56:23.333 回答