0

我正在尝试连接到 Google 的 MQTT 服务器,但出现错误我创建了所有证书并注册了我的设备 (Adafruit huzzah32)

并且文档说您连接到mqtt.googleapis.com:8883

所以我愿意

WiFiClientSecure wifi;
MQTTClient client;
client.begin("mqtt.googleapis.com", 8883, wifi);

当我尝试连接时,我使用设备路径

const char* jwt = "{json web token}";
const char* device = "projects/{project-id}/locations/{cloud-region}/registries/{registry-id}/devices/{device-id}";

Serial.print("Connecting to mqtt");
while (!client.connect(device,"unused",jwt)) {
    Serial.print(".");
    delay(1000);
}

Serial.println();
Serial.println("Connected to mqtt");

但它从不连接

我通过调用验证了谷歌证书, openssl s_client -showcerts -connect mqtt.googleapis.com:8883 并输入了我的 RSA 私钥和证书密钥

wifi.setCACert(googleCertificate2);
wifi.setCertificate(myCertificate);
wifi.setPrivateKey(privateCert);

我究竟做错了什么?

这是连接文档 https://cloud.google.com/iot/docs/how-tos/mqtt-bridge

更新

我做了一个快速的java示例,看看我是否可以连接他们用于连接的示例,我得到一个MqttException说法Bad user name or password (4)

这是代码

private void doStuff(){
        String clientId = String.format("ssl://%s:%s", "mqtt.googleapis.com", 8883);
        String mqttClientId = String.format("projects/%s/locations/%s/registries/%s/devices/%s","{project_id}", "us-central1", "{register}", "{device}");
        MqttConnectOptions connectOptions = new MqttConnectOptions();
        connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);

        Properties sslProps = new Properties();
        sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
        connectOptions.setSSLProperties(sslProps);

        connectOptions.setUserName("unused");


        try{
            String jwt = createJwtRsa("{project-id}");
            connectOptions.setPassword(jwt.toCharArray());
            MqttClient client = new MqttClient(clientId, mqttClientId, new MemoryPersistence());

            while(!client.isConnected()){
                try{
                    client.connect(connectOptions);
                }catch (MqttException e) {
                    e.printStackTrace();
                }
            }
            Log.d("","");
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    private String createJwtRsa(String projectId) throws Exception {
        DateTime now = new DateTime();
        JwtBuilder jwtBuilder =
                Jwts.builder().setIssuedAt(now.toDate()).setExpiration(now.plusDays(1000000).toDate()).setAudience(projectId);

        byte[] keyBytes = readBytes(getAssets().open("rsa_private_pkcs8"));
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");

        PrivateKey k = kf.generatePrivate(spec);

        return jwtBuilder.signWith(SignatureAlgorithm.RS256, k).compact();
    }

正如您在此处看到的,我已将 IoT 服务帐户添加到 IAM 在此处输入图像描述

这是否意味着我使用 openssl 生成的密钥不正确?

4

2 回答 2

1

我的问题最终是我试图在我的 Json Web 令牌上设置一个非常大的到期日期(故意这样我就不必继续生成新的,因为我还没有找到在 arduino 中这样做的方法)它看起来像google 的 mqtt 服务器在一天内不接受任何内容,因此必须每天更新密钥。

此外,为了连接到 MQTT 服务器,我必须将 arduino 上 MqttClient 的缓冲区大小更改为 1024 字节的缓冲区大小。

MQTTClient client(1024);

少的话我会得到一个错误,说缓冲区不够大。

于 2018-03-03T23:29:06.773 回答
0

这里正在解释IAM角色......这里的段落听起来像你所描述的:

在 Google Cloud Platform Console 的 IAM 页面上,验证角色 Cloud IoT Core Service Agent 是否出现在相关项目服务帐户的成员列表中。(查找以@gcp-sa-cloudiot.iam.gserviceaccount.com 结尾的项目服务帐户。)

如果 Cloud IoT Core 服务代理角色未出现在成员列表中,请使用 gcloud 将 cloudiot.serviceAgent 角色添加到相关项目服务帐户。此角色包括发布到 Pub/Sub 主题的权限。

如果尚未安装它,所有这些 CLI 命令都需要Cloud SDKgcloud,它可用于列出和编辑配置(所有这些都可以通过控制台完成)......这可能更容易,因为那里的所有示例也都使用它。

更新...

关于 JWT 刷新令牌,请参阅本文或有一些问答或规范:JSON Web Token (JWT)JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants。这是另一篇相关文章:https ://medium.com/google-cloud/refreshing-json-web-tokens-jwts-for-google-cloud-iot-core-897318df3836

于 2018-03-02T17:00:59.553 回答