certificate_pinning_httpclient_plus 1.0.0 copy "certificate_pinning_httpclient_plus: ^1.0.0" to clipboard
certificate_pinning_httpclient_plus: ^1.0.0 copied to clipboard

An implementation of Dart's HttpClient with certificate pinning against SPKI hashes, for Android, iOS, macOS, Linux and Windows.

certificate_pinning_httpclient_plus #

pub package license: MIT

An implementation of Dart's HttpClient with certificate pinning against SPKI (Subject Public Key Info) SHA-256 hashes.

Because it implements dart:io's HttpClient interface, it drops into anything that accepts one — package:http's IOClient, Dio's IOHttpClientAdapter, or direct dart:io usage.

Platform support #

Platform Supported Native implementation Minimum version
Android HttpsURLConnection API 21
iOS NSURLSession 12.0
macOS NSURLSession 10.14
Linux OpenSSL
Windows WinHTTP + CryptoAPI 10

Linux build requirement: the plugin links against OpenSSL, so the development headers must be present on the build machine: sudo apt-get install libssl-dev (Debian/Ubuntu) or sudo dnf install openssl-devel (Fedora).

macOS entitlement: sandboxed macOS apps cannot make outbound connections unless com.apple.security.network.client is set. Add it to both macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlementsflutter create does not add it for you.

<key>com.apple.security.network.client</key>
<true/>

Android: the plugin's manifest already declares INTERNET and ACCESS_NETWORK_STATE, which are merged into your app.

Installation #

dependencies:
  certificate_pinning_httpclient_plus: ^1.0.0

Getting your pin #

Pins are the base64-encoded SHA-256 digest of a certificate's SPKI. The client logs the SPKI hash of every certificate in the chain, so the simplest way to get yours is to make one request and read the log.

You can also compute it ahead of time with GnuTLS — look for the Public Key PIN line:

gnutls-cli --print-cert example.com

Or with OpenSSL:

openssl s_client -connect example.com:443 </dev/null 2>/dev/null \
  | openssl x509 -pubkey -noout \
  | openssl pkey -pubin -outform der \
  | openssl dgst -sha256 -binary \
  | openssl enc -base64

Usage #

import 'package:certificate_pinning_httpclient_plus/certificate_pinning_httpclient_plus.dart';

const pins = ["S4kZuhQQ1DPcMOCYFQXD0gG+UW0zmyVx6roNWpRl65I="];

With dart:io #

final client = CertificatePinningHttpClient(pins);
final request = await client.getUrl(Uri.parse("https://example.com"));
final response = await request.close();

With package:http #

import 'package:http/io_client.dart';

final client = IOClient(CertificatePinningHttpClient(pins));
final response = await client.get(Uri.parse("https://example.com"));

With Dio #

import 'package:dio/dio.dart';
import 'package:dio/io.dart';

final dio = Dio();
dio.httpClientAdapter = IOHttpClientAdapter(
  createHttpClient: () => CertificatePinningHttpClient(pins),
);

Disabling logs in release builds #

import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';

Logger.level = kDebugMode ? Level.debug : Level.nothing;

How it works #

  1. On the first request to a host, the certificate chain is fetched natively via a MethodChannel and cached per host.
  2. The SHA-256 digest of each certificate's SPKI is compared against your pins.
  3. Only the matching certificates are installed into a SecurityContext as trusted certificates, and the request is made through an HttpClient built on that context.

If no certificate matches, the security context trusts nothing and the connection fails. On a pinning failure the cached chain for that host is discarded, so a legitimate certificate rotation recovers on the next request while a MitM attempt keeps failing.

Pinning to a leaf certificate means requests break the moment that certificate rotates. Pin the intermediate, or supply several pins (current plus a backup), if you need rotation headroom.

Credits #

This package is a maintained continuation of sebkoller/certificate_pinning_httpclient, which is no longer updated. It adds macOS, Linux and Windows support on top of the original Android and iOS implementations.

The Android and Apple native implementations originate from approov/approov-service-flutter-httpclient by CriticalBlue Ltd.

License #

MIT — see LICENSE. Copyright notices for all upstream authors are retained there.

0
likes
140
points
39
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

An implementation of Dart's HttpClient with certificate pinning against SPKI hashes, for Android, iOS, macOS, Linux and Windows.

Repository (GitHub)
View/report issues

Topics

#security #networking #http #tls #certificates

License

MIT (license)

Dependencies

asn1lib, crypto, flutter, logger, pem

More

Packages that depend on certificate_pinning_httpclient_plus

Packages that implement certificate_pinning_httpclient_plus