2016-07-26 36 views
0

Ich baue ein Hardwaregerät, das eine Verbindung zur AWS IOT-Plattform herstellt. Laut Dokumentation erfolgt die Authentifizierung mit der aws iot-Plattform mit TLS. Ich habe die Stammzertifizierungsstelle, den Clientschlüssel und die Clientzertifikatdateien auf dem Gerät, die den Zugriff autorisieren. Gibt es eine Möglichkeit, diese Dateien im HTTP-Header zu verwenden, während Sie die POST-Anfrage stellen? Wenn das so ist, wie? Hier ist der Code für die Energia IDE (basierend auf der Arduino IDE) und die WiFiClient Methoden.Clientzertifikate in eine HTTPS-POST-Anforderung einfügen

if (client.sslConnect(aws_endpoint, 443)) 
{ 
    Serial.println("\nConnected to AWS endpoint"); 

    String PostData = "{\"value1\" : \"testValue\", \"value2\" : \"Hello\", \"value3\" : \"World!\" }"; 

    request = "POST /things/"; 
    request += thingname; 
    request += "/shadow"; 
    request += " HTTP/1.1"; 
    Serial.print("Request:\t"); Serial.println(request); 
    Serial.print("Post data:\t"); Serial.println(PostData); 

    client.println(request); 
    client.println("Host: "); 
    client.println(aws_endpoint); 
    client.println(":443"); 
    client.println("User-Agent: Energia/1.1"); 
    client.println("Connection: close"); 
    client.println("Content-Type: application/json"); 
    client.print("Content-Length: "); client.println(PostData.length()); 
    client.println(); 
    client.println(PostData); 
    client.println(); 
} 
else 
{ 
    Serial.println("Connection failed"); 
} 

Serial.println(); 
Serial.println("Server response:"); 
Serial.println(); 

// Capture response from the server. (10 second timeout) 
long timeOut = 5000; 
long lastTime = millis(); 

while((millis()-lastTime) < timeOut) 
{ // Wait for incoming response from server 
    while (client.available()) 
    { // Characters incoming from the server 
    char c = client.read();   // Read characters 
    Serial.write(c); 
    } 
} 

Dies ergibt jedoch einen Authentifizierungsfehler:

HTTP/1.1 403 Forbidden 
content-type: application/json 
content-length: 91 
date: Tue, 26 Jul 2016 11:46:59 GMT 
x-amzn-RequestId: 4d5388a9-e3c4-460a-b674-c3f971f3330d 
connection: Keep-Alive 
x-amzn-ErrorType: ForbiddenException: 

{"message":"Missing Authentication Token","traceId":"4d5388a9-e3c4-460a-b674-c3f971f3330d"} 
+1

Die TLS-Clientzertifikate werden als Teil Ihres Aufrufs 'client.sslConnect()' gesendet/verwendet, nicht als Teil der HTTP-Anforderung. Der TLS-Handshake (und der Austausch/die Validierung von Client- und Serverzertifikaten) findet statt, bevor eine HTTP-Nachricht gesendet wird. – Castaglia

+0

Jetzt, da ich daran denke, denke ich, das ist der Grund, warum die Verbindung in erster Linie erfolgreich ist. Was ist dann der "Fehlende Authentifizierungs-Token" Fehler? und wie repariere ich das? – hpb

+1

Gute Frage. [Dieser AWS-Forenbeitrag] (https://forums.aws.amazon.com/thread.jspa?threadID=221078) schlägt vor, dass Sie _may_ Port 8443 (nicht Port 443) für die Schatten-API verwenden müssen. Ich würde auch vorschlagen, dass Sie überprüfen, dass Ihre 'client.println()' Funktion CRLF, nicht nur LF, an das Ende der Zeichenfolgen anfügt (wie HTTP erfordert CRLF line terminations. – Castaglia

Antwort

1

Die TLS-Client-Zertifikate als Teil Ihres client.sslConnect() Anruf gesendet/verwendet werden würde, die HTTP-Anforderung nicht als Teil. Der TLS-Handshake (und der Austausch/die Validierung von Client- und Serverzertifikaten) findet statt, bevor eine HTTP-Nachricht gesendet wird.

This AWS forums post schlägt vor, dass Sie Port 8443 (nicht Port 443) für die Schatten API verwenden müssen. Es sieht aus wie die Verwendung/Anforderung von TLS gegenseitige Authentifizierung (über Zertifikate), gegenüber die Verwendung von AWS SIGv4-Header, wird von AWS IOT basierend auf dem verwendeten Port bestimmt.

Hoffe, das hilft!