Xamarin PCL.HttpClient для корпоративных SharePoint не работает [дубликат]

111
задан David Grinberg 24 March 2015 в 17:02
поделиться

11 ответов

Обновление на основе последней документации для Android (март 2017 года):

Когда вы получаете этот тип ошибки:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

проблема может быть одной из следующих:

  1. CA, выдавший сертификат сервера, был неизвестен
  2. Сертификат сервера не был подписан ЦС, но был подписан сам по себе
  3. . Конфигурация сервера Отсутствие промежуточного CA

Решение состоит в том, чтобы научить HttpsURLConnection доверять определенному набору ЦС. Как? Пожалуйста, проверьте https://developer.android.com/training/articles/security-ssl.html#CommonProblems

Другие, которые используют AsyncHTTPClient из библиотеки com.loopj.android:android-async-http проверьте Настройка AsyncHttpClient для использования HTTPS .

56
ответ дан Community 26 August 2018 в 23:06
поделиться

В телефонах Gingerbread я всегда получаю эту ошибку: Trust Anchor not found for Android SSL Connection, даже если я настроюсь полагаться на свой сертификат.

Вот код, который я использую (на языке Scala):

object Security {
    private def createCtxSsl(ctx: Context) = {
        val cer = {
            val is = ctx.getAssets.open("mycertificate.crt")
            try
                CertificateFactory.getInstance("X.509").generateCertificate(is)
            finally
                is.close()
        }
        val key = KeyStore.getInstance(KeyStore.getDefaultType)
        key.load(null, null)
        key.setCertificateEntry("ca", cer)

        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(key)

        val c = SSLContext.getInstance("TLS")
        c.init(null, tmf.getTrustManagers, null)
        c
    }

    def prepare(url: HttpURLConnection)(implicit ctx: Context) {
        url match {
            case https: HttpsURLConnection ⇒
                val cSsl = ctxSsl match {
                    case None ⇒
                        val res = createCtxSsl(ctx)
                        ctxSsl = Some(res)
                        res
                    case Some(c) ⇒ c
                }
                https.setSSLSocketFactory(cSsl.getSocketFactory)
            case _ ⇒
        }
    }

    def noSecurity(url: HttpURLConnection) {
        url match {
            case https: HttpsURLConnection ⇒
                https.setHostnameVerifier(new HostnameVerifier {
                    override def verify(hostname: String, session: SSLSession) = true
                })
            case _ ⇒
        }
    }
}

, и вот код подключения:

def connect(securize: HttpURLConnection ⇒ Unit) {
    val conn = url.openConnection().asInstanceOf[HttpURLConnection]
    securize(conn)
    conn.connect();
    ....
}

try {
    connect(Security.prepare)
} catch {
    case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ ⇒
        connect(Security.noSecurity)
}

В принципе, я настраиваю доверие к своему пользовательскому сертификату. Если это не удается, я отключу безопасность. Это не самый лучший вариант, но единственный выбор, который я знаю со старыми и багги-телефонами.

Этот пример кода можно легко перевести на Java.

0
ответ дан david.perez 26 August 2018 в 23:06
поделиться
**Set proper alias name**
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
-1
ответ дан Dayanand Waghmare 26 August 2018 в 23:06
поделиться

Ответ на очень старый пост. Но, возможно, это поможет новичку, и если не выйдет из вышеизложенного,

Объяснение: Я знаю, что никто не хочет объяснять дерьмо; скорее решение. Но в одном лайнере вы пытаетесь получить доступ к службе с вашей локальной машины на удаленную машину, которая не доверяет вашей машине. Вы требуете получить доверие от удаленного сервера.

Решение. Следующее решение предполагает, что у вас есть следующие условия:

  1. Пытается получить доступ к удаленному api с вашей локальной машины.
  2. Вы для Android-приложения
  3. Ваш удаленный сервер находится под прокси-фильтрацией (вы используете прокси-сервер в настройках вашего браузера для доступа к удаленной службе api, обычно к промежуточному или dev-серверу)
  4. Вы тестируете на реальном устройстве

Шаги:

Вам нужен файл расширения .keystore для регистрации вашего приложения. Если вы не знаете, как создать файл .keystore; затем следуйте следующему разделу Создание файла .keystore или иначе перейдите к следующему разделу. Подпишите файл Apk

Создайте файл .keystore

Откройте Android Studio. Нажмите верхнее меню «Сборка»> «Создать подписанный АПК». В следующем окне нажмите кнопку «Создать новый ...». В новом окне введите данные во все поля. Помните, что два поля Password, которые я рекомендую, должны иметь один и тот же пароль; не используйте другой пароль; а также запомнить путь сохранения в верхней части поля. После ввода всего поля нажмите кнопку OK.

Подпишите файл Apk

Теперь вам нужно создать подписанное приложение с только что созданным файлом .keystore. Выполните следующие шаги

  1. Сборка> Очистить проект, дождитесь завершения очистки
  2. Сборка> Сгенерировать подписанный APK
  3. Нажмите кнопку Choose existing...
  4. ]
  5. Выберите файл .keystore, который мы только что создали, в разделе Create .keystore file
  6. Введите тот же пароль, который вы создали, создавая в разделе Create .keystore файл. Используйте одинаковый пароль для полей Key store password и Key password. Также введите псевдоним
  7. Нажмите кнопку «Далее»
  8. . На следующем экране; которые могут отличаться в зависимости от ваших настроек в файлах build.gradle, вам нужно выбрать Build Types и Flavors.
  9. Для Build Types выберите release из выпадающего меню
  10. Однако для Flavors это зависит от ваших настроек в файле build.gradle. Выберите staging из этого поля. Я использовал следующие настройки в build.gradle, вы можете использовать то же самое, что и мое, но убедитесь, что вы изменили applicationId на ваше имя пакета productFlavors { staging { applicationId "com.yourapplication.package" manifestPlaceholders = [icon: "@drawable/ic_launcher"] buildConfigField "boolean", "CATALYST_DEBUG", "true" buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true" } production { buildConfigField "boolean", "CATALYST_DEBUG", "false" buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false" } }
  11. Нажмите на нижние два флажка Signature Versions и нажмите кнопку Finish.

Почти там:

Все трудолюбие сделано, теперь движение истины. Чтобы получить доступ к промежуточному серверу, поддерживаемому прокси-сервером, вам нужно сделать некоторые настройки на реальных Android-устройствах.

Настройки прокси-сервера в Android-устройстве:

  1. Нажмите «Настройка на телефоне Android», а затем wi-fi
  2. Длительно нажмите на подключенный Wi-Fi и выберите Modify network
  3. Нажмите Advanced options, если вы не видите поле Proxy Hostname
  4. . В поле Proxy Hostname введите IP-адрес хоста или имя, которое вы хотите подключить. Типичный промежуточный сервер будет называться как stg.api.mygoodcompany.com
  5. . Для ввода порта введите четырехзначный номер порта, например 9502
  6. Нажмите кнопку Save

One Last Stop:

Помните, что мы сгенерировали подписанный файл apk в разделе Sign APK File. Настало время установить этот файл APK.

  1. Откройте терминал и измените его на папку подписанного файла apk
  2. Подключите Android-устройство к компьютеру
  3. Удалите любой предыдущий установленный файл apk с устройства Android
  4. Запустите adb install name of the apk file
  5. Если по какой-либо причине вышеуказанная команда вернется с adb command not found. Введите полный путь как C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe install name of the apk file

Надеюсь, что проблема может быть решена. Если нет, оставьте мне комментарии.

Салам!

5
ответ дан HA SHAH 26 August 2018 в 23:06
поделиться

Вы можете доверять определенному сертификату во время выполнения. Просто загрузите его с сервера, введите активы и загрузите, как это, используя ssl-utils-android :

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

В приведенном выше примере я использовал OkHttpClient, но SSLContext может использоваться с любым клиентом на Java.

Если у вас есть какие-либо вопросы, не стесняйтесь спрашивать. Я автор этой небольшой библиотеки.

14
ответ дан mklimek 26 August 2018 в 23:06
поделиться

Сообщение об ошибке, которое я получал, было похоже, но причина в том, что срок действия подписанного сертификата уже истек. Когда клиент openssl был предпринят попытка, он дал мне причину, которая была упущена, когда я проверял диалоговое окно сертификата из firefox.

Итак, если сертификат существует в хранилище ключей и его «VALID», эта ошибка исчезнет.

4
ответ дан Robert Longson 26 August 2018 в 23:06
поделиться

У меня была та же проблема, что я обнаружил, так это то, что в файле сертификата .crt i отсутствует промежуточный сертификат. Поэтому я попросил все .crt-файлы с моего администратора сервера, а затем объединил их в обратном порядке.

Пример. 1. Root.crt 2. Inter.crt 3. myCrt.crt

в windows i выполнил копию Inter.crt + Root.crt newCertificate.crt

(Здесь я проигнорировал myCrt. crt)

Затем я предоставил файл newCertificate.crt в код через входной поток. Работа выполнена.

1
ответ дан sahan maldeniya 26 August 2018 в 23:06
поделиться

В отличие от принятого вами ответа, вам не нужен пользовательский менеджер доверия, вам нужно исправить конфигурацию вашего сервера!

Я столкнулся с той же проблемой при подключении к серверу Apache с неправильно установленным сертификатом dynadot / alphassl. Я подключаюсь с использованием HttpsUrlConnection (Java / Android), который метался -

javax.net.ssl.SSLHandshakeException: 
  java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.

. Фактическая проблема - неправильная конфигурация сервера - проверьте ее с помощью http://www.digicert.com/ help / или аналогичный, и он даже скажет вам решение:

«Сертификат не подписан доверенным органом (проверка на корневой магазин Mozilla). Если вы купили сертификат из (g3) вам, вероятно, просто нужно установить один или несколько промежуточных сертификатов . Обратитесь к поставщику сертификатов за помощью для этого для вашей серверной платформы. »

Вы также можете проверить сертификат с помощью openssl:

openssl s_client -debug -connect www.thedomaintocheck.com:443

Вероятно, вы увидите:

Verify return code: 21 (unable to verify the first certificate)

и ранее на выходе:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

Цепочка сертификатов будет содержать только один элемент (ваш сертификат):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

... но должна ссылаться на полномочия подписки в цепочке обратно на доверенную Android (Verisign, GlobalSign и т. д.):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

Инструкции (и промежуточные сертификаты) для настройки вашего сервера обычно предоставляются органом, выдавшим ваш сертификат, например: http://www.alphassl.com/support/install-root-certificate.html

После установки промежуточных сертификатов, предоставленных моим эмитентом сертификатов, у меня теперь нет ошибок при подключении с помощью HttpsUrlConnection.

155
ответ дан Stevie 26 August 2018 в 23:06
поделиться

Ошибка привязки Trust может произойти по многим причинам. Для меня это было просто, что я пытался получить доступ к https://example.com/ вместо https://www.example.com/.

Таким образом, вы можете дважды проверить свои URL-адреса, прежде чем приступать к созданию собственного Trust Manager (как и я) .

0
ответ дан Unkulunkulu 26 August 2018 в 23:06
поделиться

У меня была такая же проблема при подключении с Android-клиента на сервер Kurento. Сервер Kurento использует сертификаты jks, поэтому мне пришлось преобразовать pem в него. В качестве ввода для преобразования я использовал файл cert.pem и приводил к таким ошибкам. Но если использовать fullchain.pem вместо cert.pem - все в порядке.

2
ответ дан V.Poddubchak 26 August 2018 в 23:06
поделиться

В моем случае это произошло после обновления до Android 8.0. Самозаверяющему сертификату Android было доверено использовать алгоритм подписи SHA1withRSA. Переключение на новый сертификат с использованием алгоритма подписи SHA256withRSA устранило проблему.

0
ответ дан Zds 26 August 2018 в 23:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: