Создание HTTPS-соединения с использованием URL.openConnection() - программирование

Создание HTTPS-соединения с использованием URL.openConnection()

Я пытаюсь сделать HTTPS-соединение с сервером

В его нынешнем виде это бросает javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature., когда вызывается getOutputStream().

Этот же сайт и сертификат действительны на веб-браузере и настольных браузерах HTC. Когда я использую тот же код для доступа к , он работает (но потом жалуется на ошибку 404). Различные сообщения в StackOverflow подразумевают, что он должен "просто работать", а другие говорят, что нужно настроить свой собственный магазин ключей (или отключить всю проверку HTTPS!). Я полагаю, что разница в поведении сводится к использованию различных хранилищ корневых ключей (может ли кто-нибудь уточнить это?).

Теперь я попытался создать хранилище ключей с помощью надувного замка, но я не могу загрузить его на свое устройство.

После экспорта сертификата из Firefox я создаю хранилище ключей, используя:

keytool.exe -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -keystore res\raw\keystore

Затем он загружается и используется в приложении, используя:

InputStream stream = context.getResources().openRawResource(R.raw.keystore);
// BKS seems to be the default but we want to be explicit
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(stream, "www.onlinescoutmanager.co.uk".toCharArray());
stream.close();

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
SSLContext context2 = SSLContext.getInstance("TLS");
context2.init(null, new TrustManager[] { defaultTrustManager }, null);
sslSocketFactory = context2.getSocketFactory();

Это не работает с java.io.IOException: Wrong version of key store., когда вызывается keystore.Load().

У меня , , добавили сертификаты CA в хранилище ключей и использовали оба Bouncy Castle версии 1.45 и 1.47 для создания хранилища ключей без изменения сообщенного сообщения об ошибке.

Моя среда - Eclipse Juno 4.2.1 с JRE 1.7u9b5, работающая в Windows 8. Устройство, на котором я тестирую, - это сенсация HTC, работающая под управлением Android 2.3. Приложение имеет минимальную версию SDK 7 и целевую 15.

Если кто-нибудь может объяснить, как создать действующее хранилище ключей BKS в Windows 8 или как я могу заставить Java использовать тот же магазин ключей, что и браузер (или система?), который будет оценен.

Вы можете загрузить , как это было на момент написания, и , если требуется.

4b9b3361

Ответ 1

Bouncy Castle 1.47 использует другой заголовок версии. Можете ли вы попробовать 1.46 version, он должен работать.

keytool -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -storepass osmosm -keystore C:/keystore -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-ext-jdk15on-1.46.jar

Ответ 2

Благодаря различным людям за их намеки на это, есть несколько вещей, которые должны были быть правильными для его работы.

  • Если сертификат сайта HTTPS подписывается доверенным корневым сертификатом, он будет работать без необходимости использования SSLSocketFactory. Доверенные корневые сертификаты могут отличаться от того, что используется браузером, поэтому не предполагайте, что если он будет работать в веб-браузере Android, он будет работать в вашем приложении.
    Если это не доверенный корневой сертификат, и вы получаете такие исключения, как javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature., вам необходимо создать и загрузить хранилище ключей, как показано ниже.

  • Ключевой магазин должен быть сгенерирован с использованием поставщика Bouncy Castle (1), указав -storetype bks в командной строке keytool.
    Если Bouncy Castle установлен неправильно, это приведет к сбою с различными исключениями, включая java.security.KeyStoreException: BKS not found. Если хранилище ключей не создано с помощью провайдера Bouncy Castle, вы можете получить исключение java.io.IOException: Wrong version of key store., вызывая путаницу со следующим случаем.

  • Вам нужно использовать соответствующую версию (1, 2, 3) поставщика Bouncy Castle. В большинстве случаев это выглядит как версия 1.46.
    Это можно поместить в вашу папку JRE lib/ext/ и имя класса, добавленное в lib/security/java.security, или указав непосредственно в командной строке на keytool. Если это несовместимая версия (или тип хранилища), вы снова получите исключения по линиям java.io.IOException: Wrong version of key store..

  • Вы должны включить весь посредник и корневой сертификат. Если они отсутствуют, вы получите исключение javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found..

  • Цепочка сертификатов ДОЛЖНА быть для правильной проверки. Если это не так, вы либо получите javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: IssuerName(CN=XYZ) does not match SubjectName(CN=ABC) of signing certificate., либо снова, общий javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. Я не нашел способ заказать их в хранилище ключей, поэтому прибегал к выполнению этого кода во время выполнения.

Некоторые люди предположили, что с использованием пароля хранилища ключей длиной более 7 символов также приведет к сбою, но это не то, что я нашел.

Я думаю, что это охватывает каждую ловушку, которую я нашел, но не стесняйтесь расширять и добавлять linsk к связанным вопросам.