Flutter 从资产文件夹中添加自签名证书
Flutter add self signed certificate from asset folder
我的服务器在调用其 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;
.
绕过它
但我想让它与证书一起使用
从你的问题中并不清楚自签名证书的作用是什么。根据您的解决方法,我假设它是您安装在 HTTPS 服务器中的服务器端证书。 (这不是您想传递给服务器的客户端证书。)
因此,您需要做的是让 Dart HttpClient
信任该证书,该证书将作为 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);
我的服务器在调用其 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;
.
但我想让它与证书一起使用
从你的问题中并不清楚自签名证书的作用是什么。根据您的解决方法,我假设它是您安装在 HTTPS 服务器中的服务器端证书。 (这不是您想传递给服务器的客户端证书。)
因此,您需要做的是让 Dart HttpClient
信任该证书,该证书将作为 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);