我正在尝试连接到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();
}
这是否意味着我使用openssl生成的密钥不正确?
答案 0 :(得分:0)
这里正在解释IAM角色......段落here听起来与你描述的相似:
在Google Cloud Platform Console的IAM页面上,验证角色Cloud IoT核心服务代理是否显示在相关项目服务帐户的“成员”列表中。 (查找以@ gcp-sa-cloudiot.iam.gserviceaccount.com结尾的项目服务帐户。)
如果Cloud IoT核心服务代理角色未显示在“成员”列表中,请使用gcloud将cloudiot.serviceAgent角色添加到相关项目服务帐户。此角色包括发布到Pub / Sub主题的权限。
如果尚未安装它,则所有gcloud
CLI命令都需要Cloud SDK,这些命令可用于列出&编辑配置(其中所有配置都可以通过控制台完成)......它可能更容易,因为那里的所有例子也都使用它。
更新 ...
有关JWT刷新令牌的,请参阅此article或有一些Q & A或规范: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
答案 1 :(得分:0)
我的问题最终是因为我试图在我的Json Web令牌上设置一个非常大的过期日期(故意,所以我没有必须继续生成新的,因为我还没有找到在arduino中这样做的方法)和看起来google的mqtt服务器不接受任何一天的任何事情,所以密钥必须每天更新。
另外,为了连接到MQTT服务器,我必须将arduino上MqttClient的缓冲区大小更改为1024字节的缓冲区大小。
MQTTClient client(1024);
任何事情我会得到一个错误,说缓冲区不够大。