Flutter之Certificate pinning

Certificate pinning

ssl_pinning_plugin

Plugin for check SSL Pinning on request HTTP.

Checks the equality between the known SHA-1 or SHA-256 fingerprint and the SHA-1 or SHA-256 of the target server.

https://www.jianshu.com/p/f4b09b06aad7

对于我的应用程序,我添加了以下代码,让它只接受我的打嗝证书。SecurityContext构造函数接受一个参数withTrustedRoots,其默认为false。

ByteData data = await rootBundle.load('certs/burp.crt');
    SecurityContext context = new SecurityContext();
    context.setTrustedCertificatesBytes(data.buffer.asUint8List());
    client = HttpClient(context: context);

Flutter开发人员想要执行ssl Pinning的方法之一是通过ssl_pinning_plugin flutter插件。此插件实际上旨在发送一个HTTPS连接并验证证书,之后开发人员将信任该通道并执行HTTPS请求:

Https certificate verification(Base on Dio plugin)

There are two ways to verify the https certificate. Suppose the certificate format is PEM, the code like:

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

Another way is creating a SecurityContext when create the HttpClient:

(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate  = (client) {
    SecurityContext sc = new SecurityContext();
    //file is the path of certificate
    sc.setTrustedCertificates(file);
    HttpClient httpClient = new HttpClient(context: sc);
    return httpClient;
};

In this way, the format of certificate must be PEM or PKCS12.

你的证书如果是自签名证书,那么默认不被信任,直接请求你的服务器,就会走到此回调。如果你的证书是可信CA颁发的,并且你请求的domain包含在证书里,便会自动通过验证,因为别人伪造不了(除非CA乱发证书),这是Dart自动执行的验证,如果请求的domain没在证书里,那就说明此证书并非你的,证书检验失败,此时也会进入此回调。如果你想无论证书是否有效,都想自己检验,目前Dart没有提供这样的回调。

  Future createDio() async{
    this.dio = Dio();
    String cerData = await rootBundle.loadString("assets/cc.pem");
    this.dio.onHttpClientCreate = (HttpClient client){
      SecurityContext clientContext = SecurityContext(withTrustedRoots: true)
        ..useCertificateChainBytes(utf8.encode(cerData));
      return HttpClient(context: clientContext);
    };
    this.dio.interceptor.request.onSend = (Options options){
      return options;
    };
  }

package:http在引擎盖下使用dart:io HttpClient,并且HttpClient有几个允许证书验证的功能。由于客户机不信任自签名服务器证书,因此客户机将调用badCertificateCallback以允许您自己验证服务器证书,例如

HttpClient httpClient = new HttpClient()
..badCertificateCallback =
((X509Certificate cert, String host, int port) {
  // tests that cert is self signed, correct subject and correct date(s) 
  return (cert.issuer == cert.subject &&
      cert.subject == 'MySelfSignedCertCN' &&
      cert.endValidity.millisecondsSinceEpoch == 1234567890);
});

IOClient ioClient = new IOClient(httpClient);
// use ioClient to perform get/post operations from package:http

// don't forget to call ioClient.close() when done
// note, this also closes the underlying HttpClient

你可能感兴趣的:(Flutter之Certificate pinning)