Armen Kh.
Armen Kh.

Reputation: 315

SSL handshake error on self-signed cert in Flutter

I'm trying to connect server with self-signed cert, but I take error:
E/flutter ( 3781): HandshakeException: Handshake error in client (OS Error:
E/flutter ( 3781): CERTIFICATE_VERIFY_FAILED: Hostname mismatch(ssl_cert.c:345))
Code, where I set cert:

String path = '/storage/sdcard0/server.crt';
SecurityContext context = new SecurityContext();
context.setTrustedCertificates(path, password: 'hello');
_client = new HttpClient(context: context);

What I'm doing wrong?

If I don't set SecurityContext, I get SSL handshake error.

Upvotes: 15

Views: 23356

Answers (4)

wamae
wamae

Reputation: 830

download cert.pem

in main.dart

final ByteData data = await rootBundle.load('assets/certificates/cert.pem');
HttpOverrides.global = CustomHttpOverrides(data);
runApp(...)

in CustomHttpOverrides.dart

import 'dart:io';
import 'dart:typed_data';

class CustomHttpOverrides extends HttpOverrides {
  ByteData data;
  CustomHttpOverrides(this.data);

  @override
  HttpClient createHttpClient(SecurityContext? context) {
    final SecurityContext clientContext = SecurityContext()..setTrustedCertificatesBytes(data.buffer.asUint8List());
    return super.createHttpClient(clientContext);
  }
}

Upvotes: 0

marko
marko

Reputation: 457

In my case I got this error message, because I did not specify hostname when asked for Common Name, when creating self signed certificate (localhost is OK for simple tests):

$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.pem

Country Name (2 letter code) [AU]:SI
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:

Upvotes: 2

Armen Kh.
Armen Kh.

Reputation: 315

I used HttpClient.badCertificateCallback
Here is a code to accept any cert:

_client = new HttpClient();
_client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;

Upvotes: 13

Collin Jackson
Collin Jackson

Reputation: 116708

You can get a valid SSL certificate for free from https://letsencrypt.org/

Upvotes: 6

Related Questions