DEV Community

Harsh Bangari Rawat
Harsh Bangari Rawat

Posted on

Implementing SSL Pinning in Flutter

HTTPS

While HTTPS encrypts communication between your app and the server, it relies on certificates issued by trusted authorities to verify the server's identity. Without additional security measures, the app might accept a fraudulent certificate presented by a Man-in-the-Middle MITM attacker. This attacker could then intercept and decrypt sensitive data like login credentials or financial information.

Regular HTTPS relies on trusting external authorities to verify a server's identity. SSL pinning adds an extra layer of security by checking if the server's certificate matches a "fingerprint" stored directly in your app. If they don't match, the app can block the connection, preventing imposters from eavesdropping on your communication.

SSL certificates, like passports, expire to maintain security. Even though your app itself might not change, updating the app with the new certificate ensures a secure connection.

Manual Implementation using http package

You'll need to:

  • Load the trusted certificate (usually in PEM format) from your assets.
  • Configure the SecurityContext to trust only the loaded certificate(s).
  • Use the SecurityContext with your HTTP client (e.g., HttpClient) to make secure connections.

1. Add ssl_certificate.pem into pubspec.yaml

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true


  assets:
    - assets/ssl_certificate.pem
    - assets/app-logo.png
Enter fullscreen mode Exit fullscreen mode

2. Create Future to Load Certificate

Future<SecurityContext> get sslClient async {
  final sslCert = await rootBundle.load('assets/ssl_certificate.pem');
  SecurityContext securityContext = SecurityContext(withTrustedRoots: false);
  securityContext.setTrustedCertificatesBytes(sslCert.buffer.asInt8List());

  HttpClient client = HttpClient(context: securityContext);
  client.badCertificateCallback =
      (X509Certificate cert, String host, int port) => false;
  IOClient ioClient = IOClient(client);
  return ioClient;
}
Enter fullscreen mode Exit fullscreen mode

Here enabling SSL pinning by loading a trusted certificate from the app's assets and configuring the SecurityContext to only trust that specific certificate. This provides an extra layer of security for network connections by preventing man-in-the-middle attacks with fraudulent certificates.

Important points to consider:

  • Make sure the certificate file in your assets is valid and belongs to the server you want to connect to securely.
  • Updating the app might be necessary if the server's certificate changes and needs to be replaced in the assets.

Testing SSL Pinning

  • Valid Certificate

Your app will be able to establish a secure connection with the server.

  • Invalid Certificate ⚠️

Using an invalid or expired certificate poses a security risk. Your app won't be able to establish a secure connection with the server, potentially exposing sensitive data to eavesdroppers.
You might encounter exceptions like HandshakeException or CertificateNotFoundException in such scenarios.

By following the implementation steps you can effectively bolster the communication channel between your app and its backend servers.

Remember, SSL pinning is just one piece of the security puzzle.

Always adhere to secure coding practices and stay updated on the latest security threats to maintain a robust defense for your Flutter app.

Happy Coding! 🧑🏻‍💻

Top comments (0)