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 (который вы бы использовали, если бы ваш сертификат был на стороне клиента).

Вы не можете получить доступ к активам напрямую как Files, поскольку они связаны сборкой. Вы делаете правильные вещи, загружая их и используя ...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);
Другие вопросы по тегам