CERTIFICATE_VERIFY_FAILED: Hostname mismatch(handshake.cc:352)) for TCP connection on local server
The problem is that the CN (or SANs) in the certificate presented by the local machine do not include 192.168.8.106
.
You can verify this by using the openssl s_client
command:
openssl s_client -connect 192.168.8.106:8883 -CAfile /path/to/ca/cert
This means that the SSL/TLS library in flutter will complain that certificate doesn't reliably represent that machine.
This is important as this is what stops Man-in-the-Middle attacks.
You have 2 options to solve this.
- reissue the certificate with a CN or SAN entry with 192.168.8.106
- See if you can find a way to influence the Certificate verification. There are examples of how to do this with the dart http library (https://stackoverflow.com/a/59303283/504554) but I haven't found this in the MQTT client library (I haven't looked that hard).
You have to be very careful if you go with option 2 to ensure that you do not open up too big a hole for Man-in-the-middle attacks.
Muhammad Usama
I am a tech enthusiast working with MEAN stack, Vue.js , flutter, aws, IoT and web development. I have experience in IoT and E-Commerce based solutions. Always looking for good opportunities to utilize my skills for the betterment of society and to grow into a good developer.
Updated on December 02, 2022Comments
-
Muhammad Usama over 1 year
My code is connecting to AWS-END-POINT properly but when I tried connecting to Greengrass core using local network ip. I get this error.
E/flutter (12349): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: HandshakeException: Handshake error in client (OS Error: E/flutter (12349): CERTIFICATE_VERIFY_FAILED: Hostname mismatch(handshake.cc:352))
I have already checked the greengrass core. it's working fine. It is connecting to web client very well. I think there might be some issue of using ip address instead of URL address. but i am not sure. Can anyone help please?
The Code I am running is:
import 'dart:async'; import 'dart:io'; import 'package:mqtt_client/mqtt_client.dart'; import 'dart:convert' show utf8; import 'dart:convert'; Future<int> main() async { const String url = '192.168.8.106'; const int port = 8883; const String clientId = 'MY CLIENT ID'; MqttClient client = MqttClient(url,clientId); client.port = port; client.secure = true; final SecurityContext context = new SecurityContext(withTrustedRoots: true); context.setTrustedCertificatesBytes(utf8.encode(' CERT ')); context.useCertificateChainBytes(utf8.encode(' CERT ')); context.usePrivateKeyBytes(utf8.encode(' PRIVEATE KEY ')); client.securityContext = context; client.setProtocolV311(); // logging if you wish client.logging(on: false); print('Before Connecting'); try{ await client.connect(); }catch(e){ print('CATCH IS : '); print (e); } print('After Connecting'); if (client.connectionStatus.state == MqttConnectionState.connected) { print('iotcore client connected'); } else { client.disconnect(); } print('Sleeping....'); for (int i=1; i>0; i++) { const String topic = '\$aws/things/Pi_tmfacility_0_1/shadow/update'; Map<dynamic, dynamic> payload = {'state': { 'desired': { 'number' : i } } }; final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder(); builder.addString(json.encode(payload)); print('into the publish to get single device shadow '); client.publishMessage(topic, MqttQos.atMostOnce, builder.payload); print('Ready to Sleep'); await MqttUtilities.asyncSleep(10); print('Loop no = $i'); } print('Disconnecting'); client.disconnect(); return 0; }
-
Dev over 4 yearsopen https url "192.168.8.106:8883" in browser i think you will get certificate error coz certificate is not valid as per ip.you try to use and http url of local resource
-
Muhammad Usama over 4 yearsI am trying to make mqtts connection instead of https so obviously it would not open anything in browser. But i have connected using mqttfx desktop client and it connects instantly
-