Flutter добавить самоподписанный сертификат из папки активов - PullRequest
0 голосов
/ 09 января 2019

Мой сервер предоставляет самоподписанный сертификат при вызове своего 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 Ответ

0 голосов
/ 09 января 2019

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