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