CERTIFICATE_VERIFY_FAILED:本地服务器上 TCP 连接的主机名不匹配(handshake.cc:352))

CERTIFICATE_VERIFY_FAILED: Hostname mismatch(handshake.cc:352)) for TCP connection on local server

我的代码正确连接到 AWS-END-POINT,但是当我尝试使用本地网络 ip 连接到 Greengrass 核心时。我收到此错误。

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))

我已经检查了 greengrass 核心。它工作正常。它很好地连接到网络客户端。 我认为使用 ip 地址而不是 URL 地址可能存在一些问题。但我不确定。有人可以帮忙吗?

我 运行 的代码是:

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;
}

问题是本地机器提供的证书中的 CN(或 SAN)不包括 192.168.8.106

您可以使用 openssl s_client 命令验证这一点:

openssl s_client -connect 192.168.8.106:8883 -CAfile /path/to/ca/cert

这意味着 flutter 中的 SSL/TLS 库会抱怨证书不能可靠地代表那台机器。

这很重要,因为它可以阻止中间人攻击。

你有 2 个选项来解决这个问题。

  1. 重新颁发带有 192.168.8.106 的 CN 或 SAN 条目的证书
  2. 看看你能不能找到影响证书验证的方法。有一些关于如何使用 dart http 库 () 执行此操作的示例,但我没有在 MQTT 客户端库中找到它(我没那么难看)。

如果选择选项 2,则必须非常小心,以确保不会为中间人攻击打开太大的漏洞。

我在 flutter 应用程序中遇到了同样的错误,但我的解决方案和原因有点不同。

我的证书是“*.xxxxxx.com”(星级证书)。 (xxxxxx.com 不适用于 +18 网站,只是示例 :))

我的子域名是 sub_domain.xxxxxx.com.

解决方法很简单,但是解决起来需要时间。

“_”(下划线) 是域名中的主要问题。 我将其更改为 subdoman.xxxxxx.com 并且有效。