Search code examples
sslflutterdartgrpcself-signed

Self-signed cert for gRPC on Flutter


I have a Flutter app that communicates with a server using gRPC. The server is using a self-signed certificate for TLS. I have added the certificate to my Flutter app, and this works on Android. However on iOS I get CERTIFICATE_VERIFY_FAILED error. Does iOS just not allow self-signed certificates?

I am setting up my gRPC client as follows:

    var cert = await rootBundle.load('assets/cert.crt');
    var creds = ChannelCredentials.secure(
        certificates: cert.buffer.asUint8List().toList()
    );
    var channel = ClientChannel(
        host,
        port: port,
        options: new ChannelOptions(credentials: creds));
    return GrpcClient(channel);


Solution

  • There doesn't seem to be an obvious solution on iOS for adding a trusted, self-signed root CA. Since production will likely have a publically trusted CA, you can work around by disabling TLS verification for development only.

    Here's the relevant snippet of my full example repo:

    Future<ClientChannel> makeChannel() async {
      final caCert = await rootBundle.loadString('assets/pki/ca/ca.crt');
    
      return ClientChannel(
        'localhost',
        port: 13100,
        options: ChannelOptions(
          credentials: ChannelCredentials.secure(
            certificates: utf8.encode(caCert),
    
            // --- WORKAROUND FOR SELF-SIGNED DEVELOPMENT CA ---
            onBadCertificate: (certificate, host) => host == 'localhost:13100',
          ),
        ),
      );
    }
    

    In this case, my server is listening on localhost:13100.