Flutter добавить самоподписанный сертификат из папки активов
Мой сервер предоставляет самоподписанный сертификат при вызове его 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;
,
но я хотел бы заставить его работать с сертификатом
1 ответ
Из вашего вопроса не ясно, какова роль самозаверяющего сертификата. Исходя из вашей работы, я предполагаю, что это серверный сертификат, который вы установили на сервере HTTPS. (Это не сертификат на стороне клиента, который вы хотели бы передать на сервер.)
Итак, что вам нужно сделать, это получить дротик HttpClient
доверять этому сертификату, который будет передан ему сервером как часть рукопожатия TLS. (Установив обратный вызов, вы заставили клиента доверять любому сертификату, а не только вашему серверу.)
Для установки доверенного сертификата используйте setTrustedCertificatesBytes
на месте useCertificateChainBytes
(который вы бы использовали, если бы ваш сертификат был на стороне клиента).
Вы не можете получить доступ к активам напрямую как File
s, поскольку они связаны сборкой. Вы делаете правильные вещи, загружая их и используя ...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);