Недавно выложили вопрос по поводу HttpClient
сверх https ( находится здесь ). Я добился определенных успехов, но столкнулся с новыми проблемами. Как и с моей последней проблемой, я не могу найти пример где-нибудь, что работает для меня. По сути, я хочу, чтобы мой клиент принял любой сертификат (потому что я указываю только на один сервер), но я продолжаю получатьjavax.net.ssl.SSLException: Not trusted server certificate exception.
Итак, вот что я имею:
public void connect() throws A_WHOLE_BUNCH_OF_EXCEPTIONS {
HttpPost post = new HttpPost(new URI(PROD_URL));
post.setEntity(new StringEntity(BODY));
KeyStore trusted = KeyStore.getInstance("BKS");
trusted.load(null, "".toCharArray());
SSLSocketFactory sslf = new SSLSocketFactory(trusted);
sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme ("https", sslf, 443));
SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
schemeRegistry);
HttpClient client = new DefaultHttpClient(cm, post.getParams());
HttpResponse result = client.execute(post);
}
И вот ошибка, которую я получаю:
W/System.err( 901): javax.net.ssl.SSLException: Not trusted server certificate
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360)
W/System.err( 901): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321)
W/System.err( 901): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:129)
W/System.err( 901): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
W/System.err( 901): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
W/System.err( 901): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:129)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.access$0(MainActivity.java:77)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity$2.run(MainActivity.java:49)
W/System.err( 901): Caused by: java.security.cert.CertificateException: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:157)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:355)
W/System.err( 901): ... 12 more
W/System.err( 901): Caused by: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty
W/System.err( 901): at java.security.cert.PKIXParameters.checkTrustAnchors(PKIXParameters.java:645)
W/System.err( 901): at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:89)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.<init>(TrustManagerImpl.java:89)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl.engineGetTrustManagers(TrustManagerFactoryImpl.java:134)
W/System.err( 901): at javax.net.ssl.TrustManagerFactory.getTrustManagers(TrustManagerFactory.java:226)W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.createTrustManagers(SSLSocketFactory.java:263)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:190)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:216)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:107)
W/System.err( 901): ... 2 more
java
ssl
https
certificate
apache-httpclient-4.x
harrisonlee
источник
источник
Ответы:
Примечание. Не реализуйте это в рабочем коде, который вы когда-либо собираетесь использовать в сети, которой вы не полностью доверяете. Особенно все, что происходит через общедоступный интернет.
Ваш вопрос как раз то, что я хочу знать. После того, как я сделал некоторые поиски, вывод следующий.
В HttpClient вы должны создать собственный класс из org.apache.http.conn.ssl.SSLSocketFactory, а не один org.apache.http.conn.ssl.SSLSocketFactory. Некоторые подсказки можно найти в этом посте. Пользовательская обработка SSL перестала работать на Android 2.2 FroYo .
Пример как ...
и использовать этот класс при создании экземпляра HttpClient.
Кстати, ссылка ниже предназначена для тех, кто ищет решение HttpURLConnection. HTTP-соединение Android
Я протестировал два вышеупомянутых решения на froyo, и все они работают как шарм в моих случаях. Наконец, использование HttpURLConnection может столкнуться с проблемами перенаправления, но это выходит за рамки темы.
Примечание: прежде чем вы решите доверять всем сертификатам, вы, вероятно, должны хорошо знать сайт и не навредить ему для конечного пользователя.
В самом деле, риск, который вы принимаете, должен быть тщательно продуман, включая эффект макета сайта хакера, упомянутый в следующих комментариях, которые я высоко оценил. В некоторых ситуациях, хотя может быть сложно позаботиться о всех сертификатах, вам лучше знать неявные недостатки, чтобы доверять всем им.
источник
getAcceptedIssuers()
не разрешено возвращать ноль.В основном у вас есть четыре возможных решения для исправления исключения «Не доверенные» на Android с использованием httpclient:
В этом ответе используется решение № 4, которое мне кажется наиболее надежным.
Решение состоит в том, чтобы использовать SSLSocketFactory, который может принимать несколько хранилищ ключей, что позволяет вам предоставлять свой собственный хранилище ключей с собственными сертификатами. Это позволяет загружать дополнительные сертификаты верхнего уровня, такие как Thawte, которые могут отсутствовать на некоторых устройствах Android. Это также позволяет вам загружать собственные подписанные сертификаты. Сначала он будет использовать встроенные сертификаты устройства по умолчанию и использовать ваши дополнительные сертификаты только при необходимости.
Сначала вы захотите определить, какой сертификат отсутствует в вашем хранилище ключей. Запустите следующую команду:
И вы увидите вывод, подобный следующему:
Как видите, наш корневой сертификат от Thawte. Зайдите на сайт вашего провайдера и найдите соответствующий сертификат. Для нас это было здесь , и вы можете видеть, что нам нужен был Copyright 2006.
Если вы используете самозаверяющий сертификат, вам не нужно было выполнять предыдущий шаг, поскольку у вас уже есть сертификат подписи.
Затем создайте файл хранилища ключей, содержащий отсутствующий сертификат подписи. У Crazybob есть детали, как это сделать на Android , но идея состоит в том, чтобы сделать следующее:
Если у вас его еще нет, загрузите библиотеку поставщика надувных замков по адресу : http://www.bouncycastle.org/latest_releases.html . Это пойдет на ваш classpath ниже.
Запустите команду, чтобы извлечь сертификат с сервера и создать файл pem. В этом случае mycert.pem.
Затем выполните следующие команды, чтобы создать хранилище ключей.
Вы заметите, что приведенный выше скрипт помещает результат в
res/raw/mystore.bks
. Теперь у вас есть файл, который вы загрузите в свое приложение для Android, которое предоставляет недостающие сертификаты.Для этого зарегистрируйте свой SSLSocketFactory для схемы SSL:
Чтобы создать свой SSLSocketFactory:
И наконец, код AdditionalKeyStoresSSLSocketFactory, который принимает ваш новый KeyStore и проверяет, не удается ли встроенному KeyStore проверить сертификат SSL:
источник
http://stackoverflow.com/questions/7822381/need-help-understanding-certificate-chains
Добавьте этот код до
HttpsURLConnection
и это будет сделано. Я понял.Я надеюсь, это поможет вам.
источник
Это плохая идея. Доверять любому сертификату только (очень) немного лучше, чем вообще не использовать SSL. Когда вы говорите: «Я хочу, чтобы мой клиент принял любой сертификат (потому что я указываю только на один сервер)», вы подразумеваете, что указание на «один сервер» каким-то образом безопасно, чего нет в общедоступной сети.
Вы полностью открыты для атаки «человек посередине», доверяя любому сертификату. Любой может прокси-соединение через ваше соединение, установив отдельное SSL-соединение с вами и с конечным сервером. MITM получает доступ ко всем вашим запросам и ответам. Если вам не нужен действительно SSL в первую очередь (ваше сообщение не имеет ничего чувствительного и не выполняет аутентификацию), вам не следует слепо доверять всем сертификатам.
Вы должны рассмотреть возможность добавления общедоступного сертификата в jks с помощью keytool и использовать его для создания фабрики сокетов, например:
На это есть одно предостережение. Срок действия сертификата истекает, и код перестанет работать в это время. Вы можете легко определить, когда это произойдет, посмотрев на сертификат.
источник
null
вSSLContext.init). You should also use the default algorithms (KMF/TMF.getDefaultAlgorithm() ), instead of hard-coding
SunX509` (тем более, что по умолчанию для TMF фактическиPKIX
используется Sun / Oracle JVM).myjks.jks
взялось?Вы можете отключить проверку SSL HttpURLConnection для целей тестирования, начиная с API 8:
источник
org.apache.http.conn.ssl.AllowAllHostnameVerifier
устарел.AllowAllHostnameVerifier
заменяется наNoopHostnameVerifier
"API HttpComponents изменился. Это работает с кодом ниже.
источник
Код выше в https://stackoverflow.com/a/6378872/1553004 правильный, за исключением того, что он ДОЛЖЕН также вызывать верификатор имени хоста:
Я подписался на stackoverflow специально, чтобы добавить это исправление. Обратите внимание на мое предупреждение!
источник
Я добавляю ответ для тех, кто использует httpclient-4.5 и, вероятно, работает и для 4.4.
источник
Доверие всем сертификатам не было для меня реальной альтернативой, поэтому я сделал следующее, чтобы HttpsURLConnection доверял новому сертификату (см. Также http://nelenkov.blogspot.jp/2011/12/using-custom-certificate-trust-store- on.html ).
Получить сертификат; Я сделал это, экспортировав сертификат в Firefox (нажмите на маленький значок замка, получите информацию о сертификате, нажмите экспорт), а затем использовали portecle для экспорта склада доверенных сертификатов (BKS).
Загрузите хранилище доверенных сертификатов из /res/raw/geotrust_cert.bks со следующим кодом:
источник
IOExceptionjavax.net.ssl.SSLPeerUnverifiedException: No peer certificate
, Это происходит при выполнении фактического вызова execute для HttpClient после выполнения вышеуказанной настройки.Вот очень простая версия с использованием кода httpclient 4.1.2. Затем его можно изменить на любой алгоритм доверия, который вы считаете нужным.
источник
Я посмотрел ответ от "emmby" (ответил 16 июня '11 в 21:29), пункт № 4: "Создайте собственный SSLSocketFactory, который использует встроенный сертификат KeyStore, но использует альтернативный KeyStore для всего, что дает сбой проверить по умолчанию. "
Это упрощенная реализация. Загрузите системное хранилище ключей и объедините его с хранилищем ключей приложения.
Простой режим для преобразования из JKS в BKS:
* Примечание. В Android 4.0 (ICS) изменился трастовый магазин. Дополнительная информация: http://nelenkov.blogspot.com.es/2011/12/ics-trust-store-implementation.html.
источник
Для тех, кто хочет, чтобы все сертификаты работали (для целей тестирования) над OAuth, выполните следующие действия:
1) Загрузите исходный код API OAuth для Android здесь: https://github.com/kaeppler/signpost
2) Найдите файл класса "CommonsHttpOAuthProvider"
3) Измените его, как показано ниже:
«MySSLSocketFactory» выше основан на принятом ответе. Чтобы сделать это еще проще, вот полный класс:
}
Надеюсь, это кому-нибудь поможет.
источник
HttpClient
и по HTTPS; не OAuth для Android из проекта GitHub.Я использовал это, и это работает для меня на всех ОС.
источник
Просто добавление
-Dtrust_all_cert=true
в VM аргументов должно подойти. Этот аргумент говорит Java игнорировать проверки сертификатов.источник
Любой, кто до сих пор борется с SSL-сертификатами StartCom на Android 2.1, посещает https://www.startssl.com/certs/ и скачивает ca.pem, теперь в ответе, предоставленном @emmby replace
с
Должно работать из коробки. Я боролся с этим более суток, даже после того, как @emmby дал идеальный ответ .. Надеюсь, это кому-нибудь поможет ...
источник
использовать этот класс
}
источник
введите описание изображения здесь
Сспи не удалось в xamarin android.
Я нашел это решение; поставить этот код, прежде чем нажать на ссылку HTTPS
источник
работать со всеми https
источник
Выше было много ответов, но я не смог заставить ни один из них работать правильно (из-за моего ограниченного времени), поэтому для всех, кто находится в такой же ситуации, вы можете попробовать приведенный ниже код, который отлично подошел для моих целей тестирования Java:
и звоните как:
Ссылка: http://tech.chitgoks.com/2011/04/24/how-to-avoid-javax-net-ssl-sslpeerunverifiedexception-peer-not-authenticated-problem-using-apache-httpclient/
источник
Просто используйте это -
источник
Даниэль ответил хорошо, но мне пришлось изменить этот код ...
к этому коду ...
заставить его работать.
источник