7

我的服务器在调用其 HTTPS API 时提供了自签名证书。我在文件asset夹中有证书文件并在pubspec.yaml 我尝试将证书传递给SecurityContext然后使用该上下文创建一个HttpClient. 但是我将证书传递给的方式SecurityContext不起作用。这是代码:

Future<ByteData> getFileData(String path) async {
    return await rootBundle.load(path);
}

void initializeHttpClient() async {
    try {
         Future<ByteData> data = getFileData('assets/raw/certificate.crt');
         await data.then((value) {
             var context = SecurityContext.defaultContext;
             context.useCertificateChainBytes(value.buffer.asInt8List());
             client = HttpClient(context: context);
         });

    } on Exception catch (exception) {
         print(exception.toString());
    }
}

SecurityContext两种方法:
1)useCertificateChain()这接受一个文件路径。但是当我在我的资产文件夹('assets/raw/certificate.crt')中给出文件的路径时。它说找不到文件。
2)useCertificateChainBytes()上面的代码就是使用这种方法的。但这也给了我类似(意外的文件结尾)的错误。

目前解决方案

我正在使用client.badCertificateCallback = (X509Certificate cert, String host, int port)=> true;.

但我想让它与证书一起使用

4

1 回答 1

15

从您的问题中不清楚自签名证书的作用是什么。根据您的工作,我假设它是您在 HTTPS 服务器中安装的服务器端证书。(这不是您要传递给服务器的客户端证书。)

因此,您需要做的是让 DartHttpClient信任该证书,该证书将作为 TLS 握手的一部分由服务器传递给它。(通过设置回调,您使客户端信任任何证书,而不仅仅是您的服务器的。)

设置受信任的证书使用setTrustedCertificatesBytes代替useCertificateChainBytes(如果您的证书是客户端证书,您将使用该证书)。

您不能直接访问资产,File因为它们是由构建捆绑的。通过加载它们并使用...Bytes方法,您正在做正确的事情。您可以像这样提高代码的可读性(删除then)。另外,请注意细微的变化Uint8List

ByteData data = await rootBundle.load('assets/raw/certificate.crt');
SecurityContext context = SecurityContext.defaultContext;
context.setTrustedCertificatesBytes(data.buffer.asUint8List());
client = HttpClient(context: context);
于 2019-01-09T12:36:41.110 回答