我遇到了一个困境。我正在编写一个客户端/服务器应用程序。前端使用Flutter和Dio http包,后端是Java。后端REST API使用TLS证书进行安全保护。
正如许多其他问题所指出的那样,Flutter在所有平台上似乎都没有访问系统CA证书存储的权限。这是个问题,因为我打算允许服务器应用程序进行自托管,这意味着可以使用来自各种CA的证书,因此我的HTTP客户端需要支持Typical Web Browser支持的所有CA。
Dio显然允许您设置受信任的证书链,但我想知道如何最好地利用它。
有人以前遇到过这个问题吗?你实施了什么解决方案?
我目前想到的解决方案如下:
1. 允许用户“上传”ca证书包并将字节存储在shared_preferences中(对用户来说很难)
2. 找到另一种验证证书的方法,例如使用用户输入的指纹?(不太难,让所有证书无法通过原始验证,然后使用存储的拇指印针对onBadCertificate进行自定义验证)
3. 找到一个提供访问系统证书存储库的软件包
4. 在应用程序内部发布大量知名CA证书,并以某种方式使用Dio信任它们
我提出的另一个问题是,Dio似乎忽略了我的onBadCertificate方法。我在ConnectionManager中声明了这个方法,是否不应该这样做?
以下是被忽略的代码:
正如许多其他问题所指出的那样,Flutter在所有平台上似乎都没有访问系统CA证书存储的权限。这是个问题,因为我打算允许服务器应用程序进行自托管,这意味着可以使用来自各种CA的证书,因此我的HTTP客户端需要支持Typical Web Browser支持的所有CA。
Dio显然允许您设置受信任的证书链,但我想知道如何最好地利用它。
有人以前遇到过这个问题吗?你实施了什么解决方案?
我目前想到的解决方案如下:
1. 允许用户“上传”ca证书包并将字节存储在shared_preferences中(对用户来说很难)
2. 找到另一种验证证书的方法,例如使用用户输入的指纹?(不太难,让所有证书无法通过原始验证,然后使用存储的拇指印针对onBadCertificate进行自定义验证)
3. 找到一个提供访问系统证书存储库的软件包
4. 在应用程序内部发布大量知名CA证书,并以某种方式使用Dio信任它们
我提出的另一个问题是,Dio似乎忽略了我的onBadCertificate方法。我在ConnectionManager中声明了这个方法,是否不应该这样做?
以下是被忽略的代码:
var dio = Dio()
..options.baseUrl = server
..interceptors.add(LogInterceptor())
..interceptors.add(CookieManager(cookieJar))
..httpClientAdapter = Http2Adapter(
ConnectionManager(
idleTimeout: 10000,
// Ignore bad certificate
onClientCreate: (_, config) => {
//config.context?.setTrustedCertificatesBytes(File("/assets/certs/wildcard.pem").readAsBytesSync()),
config.onBadCertificate = (_) => true, // <-- ignored, should bypass check
}
),
);
编辑:
如评论中所述,Flutter 实际上能够使用系统的 CA 证书库。如果我在测试其他平台时遇到证书问题,我会进行更新。但这个问题已经解决了!