title: Flutter Websocket Secure error: CERTIFICATE_VERIFY_FAILED: Hostname mismatch
body: <p>I am using secure websocket in Flutter connect to server,  my server side is using self-signed certificate. in flutter clent, I store the trusted <code>CA.pem </code> in local assets.  and load it to verify server certificate. my code is like this:</p>
  <pre class="lang-dart prettyprint-override"><code>void main() async {
    ByteData data = await rootBundle.load('assets/data/ca-cert.pem');
    runApp( child: const App());
  }
  class MyHttpOverrides extends HttpOverrides {
    final ByteData data;
  
    MyHttpOverrides({required this.data});
  
    @override
    HttpClient createHttpClient(SecurityContext? context) {
      final SecurityContext clientContext = SecurityContext()..
      setTrustedCertificatesBytes(data.buffer.asUint8List())
      Log().i(&quot;cert.pre=&quot; + data.buffer.asUint8List().toString());
      return super.createHttpClient(clientContext);
    
    }
  }
  </code></pre>
  <p>But I keep getting this error:</p>
  <pre><code>WebSocketChannelException: HandshakeException: Handshake error in client (OS Error: 
  CERTIFICATE_VERIFY_FAILED: Hostname mismatch(handshake.cc:359))
  </code></pre>
  <p>Most answers on internet are like this</p>
  <pre class="lang-dart prettyprint-override"><code>class MyHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext context) {
  return super.createHttpClient(context)
    ..badCertificateCallback =
        (X509Certificate cert, String host, int port) =&gt; true; }}
  </code></pre>
  <p>but I would say this is not a safe solution for product environment. because you just accept any untrusted certificate.
  I also try kotlin version in native android runing on same deivce. it has no issues with below codes:</p>
  <pre class="lang-kotlin prettyprint-override"><code>if (address.indexOf(&quot;wss&quot;) == 0) {
      var sslContext: SSLContext? = null
      try {
          sslContext = SSLContext.getInstance(&quot;TLS&quot;)
          val cf = CertificateFactory.getInstance(&quot;X.509&quot;)
          val instream = context.assets.open(&quot;ca-cert.pem&quot;) 
          val ca = cf.generateCertificate(instream)
          val trustStore = KeyStore.getInstance(KeyStore.getDefaultType())
          trustStore.load(null, null)
          trustStore.setCertificateEntry(&quot;ca&quot;, ca)
          val trustManagerFactory =
              TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
          trustManagerFactory.init(trustStore)
          sslContext.init(null, trustManagerFactory.trustManagers, null)
      } catch (e: NoSuchAlgorithmException) {
          e.printStackTrace()
      } catch (e: CertificateException) {
          e.printStackTrace()
      } catch (e: KeyStoreException) {
          e.printStackTrace()
      } catch (e: IOException) {
          e.printStackTrace()
      } catch (e: KeyManagementException) {
          e.printStackTrace()
      }
      val factory: SSLSocketFactory? = sslContext?.socketFactory
      client.setSocketFactory(factory!!)
  }
  try {
      client.connectBlocking()
  } catch (e: InterruptedException) {
      e.printStackTrace()
  }
  </code></pre>