Steve Kim
Steve Kim

Reputation: 5591

Flutter: HTTPS certificate verification with badCertificateCallback

I am using Dio package in my Flutter app.

I need to verify the HTTPS certificate as shown in the example but I am not sure how to do this properly. Searched for hours but no good result.

Below is what I have so far:

  //This should only run if the verification is a success
  testAPI() async {
    try {
      response = await dio.post('https://someAPI.com', data: requestBody);    
      print(response);
    } catch (e) {
      print(e);
    }
  }

then, https certificate verification step:

verificationStep(){
  String PEM="XXXXX"; 
  (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate  = (client) {
    client.badCertificateCallback=(X509Certificate cert, String host, int port){
        if(cert.pem==PEM){ // Verify the certificate
            //or run testAPI() here
            return true;
        }
        return false;
    };
 };
}

If I am limiting any API calls to https://someAPI.com only, where/when do I call this verificationStep() function to verify the received certificate before processing any APIs? I am not even sure if this is the correct way of doing it.

At the end, I am trying to add network security as the app will only need to make API calls to a specific endpoint. Thus, in order to prevent any MITM attack, I am trying to add a certificate verification stage.

So far, this verification step is simply ignored or never gets to the if statement.

Any help would be much appreciated.

Thanks!

Upvotes: 0

Views: 4039

Answers (1)

Abeer Iqbal
Abeer Iqbal

Reputation: 1346

You can use HTTP default library, just also add try-catch in case of exception. I hope you will able to check your certificate there while testing on Android.

    HttpClient httpClient = new HttpClient();
              httpClient.badCertificateCallback = ((X509Certificate cert, String host, int port) {
    if(cert.pem==PEM){ // Verify the certificate
                //or run testAPI() here
                return true;
            }
        return false;}
);
          debugPrint("url: " + url + " Body:" + (body == null ? "" : body.toString()));
      try {

        httpClient.postUrl(Uri.parse(url)).then((request) {
          if (headers != null) {
            List<String> keys = headers.keys.toList();
            for (int i = 0; i < keys.length; i++) {
              request.headers.set(keys[i], headers[keys[i]]);
            }
            request.add(utf8.encode(json.encode(body)));
            request.close().then((response) {

              response.transform(utf8.decoder).join().then((body) {
                if (response != null && response.statusCode == 200 && body != null) {
                  //Success
                } else {
                  //fail
                }
              });
            }).catchError((Object error) {
              if (error != null && error.runtimeType == String) {
                debugPrint("response: " + error  ?? "");
              }

            }).whenComplete(() {
              print("Api complete");
            });
          }
        });
      } on Function catch (e, _) {
        if (e != null) {
        }
        callCompletion(null, false, completion);
        debugPrint('catch callback');
      }

Upvotes: 2

Related Questions