Intereting Posts
Предоставление приложения Android разрешения android.permission.INTERNET при отладке на устройстве Ошибка libpng: не файл PNG Какое разрешение должны иметь экраны для Android? Где установить функцию Firebase.setAndroidContext () Cocos2d-x-2.1.4: ошибка: формат не строковый литерал и аргументы формата Как перейти к определенной позиции в recyclerview внутри scrollview? В чем разница между «px», «dip», «dp» и «sp» на Android? Совместимость сеанса мультимедиа, не отображающая элементы управления Lockscreen на Pre-Lollipop Android – настроить Spinner для использования массива Вызов функций JNI в имени пакета Android, содержащем знак подчеркивания Recyclerview внутри ScrollView не плавно прокручивается В C, tan (30) дает мне отрицательное значение! Зачем? Как включить удаленный отладчик / инспектор WebKit приложения Android с помощью WebView? Как заставить WebView пропускать изображения? Как анимировать кнопку плавающего действия, используя переход к активности Android?

Как создать формат BKS (BouncyCastle) Java Keystore, который содержит цепочку сертификатов клиента

Я пишу приложение для Android, для которого требуется аутентификация клиента SSL. Я знаю, как создать хранилище JKS для настольного Java-приложения, но Android поддерживает только формат BKS. Каждый способ, которым я пытался создать хранилище ключей, приводит к следующей ошибке:
handling exception: javax.net.ssl.SSLHandshakeException: null cert chain

Таким образом, похоже, что клиент никогда не отправляет надлежащую цепочку сертификатов, возможно, потому, что я не создаю хранилище ключей должным образом. Я не могу включить отладку SSL, как я могу, на dekstop, так что это намного сложнее, чем должно быть.

Для справки: команда, которая работает для создания доверенного магазина BKS:
keytool -importcert -v -trustcacerts -file "cacert.pem" -alias ca -keystore "mySrvTruststore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-145.jar" -storetype BKS -storepass testtest


Вот команда, которую я пробовал, которая НЕ работает, чтобы создать клиентское хранилище клиентов BKS:

 cat clientkey.pem clientcert.pem cacert.pem > client.pem keytool -import -v -file <(openssl x509 -in client.pem) -alias client -keystore "clientkeystore" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-145.jar" -storetype BKS -storepass testtest 

Solutions Collecting From Web of "Как создать формат BKS (BouncyCastle) Java Keystore, который содержит цепочку сертификатов клиента"

Подробные инструкции по шагам Я следил за этим

  • Скачайте bouncycastle JAR из http://repo2.maven.org/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.46/bcprov-ext-jdk15on-1.46.jar или возьмите его из папки «doc».
  • Настройте BouncyCastle для ПК, используя один из следующих способов.
    • Добавление поставщика BC статически (рекомендуется)
      • Скопируйте файл bcprov-ext-jdk15on-1.46.jar на каждый
        • D: \ tools \ jdk1.5.0_09 \ jre \ lib \ ext (JDK (в комплекте JRE)
        • D: \ tools \ jre1.5.0_09 \ lib \ ext (JRE)
        • C: \ (местоположение, которое будет использоваться в переменной env)
      • Измените файл java.security в разделе
        • D: \ Tools \ jdk1.5.0_09 \ JRE \ Lib \ безопасность
        • D: \ Tools \ jre1.5.0_09 \ Lib \ безопасность
        • И добавьте следующую запись
          • security.provider.7 = org.bouncycastle.jce.provider.BouncyCastleProvider
      • Добавьте следующую переменную среды в раздел «Пользовательские переменные»
        • CLASSPATH =% CLASSPATH%; C: \ bcprov-доб-jdk15on-1.46.jar
    • Добавьте bcprov-ext-jdk15on-1.46.jar в CLASSPATH вашего проекта и добавьте следующую строку в свой код
      • Security.addProvider (новый BouncyCastleProvider ());
  • Создайте Keystore с помощью Bouncy Castle
    • Выполните следующую команду
      • Keytool -genkey -alias myproject -keystore C: /myproject.keystore -storepass myproject -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
    • Это создает файл C: \ myproject.keystore
    • Выполните следующую команду, чтобы проверить, правильно ли она создана или нет.
      • Keytool -list -keystore C: \ myproject.keystore -storetype BKS
  • Настройка BouncyCastle для TOMCAT

    • Откройте D: \ tools \ apache-tomcat-6.0.35 \ conf \ server.xml и добавьте следующую запись

      • <Connector port = "8443" keystorePass = "myproject" alias = "myproject" keystore = "c: /myproject.keystore" keystoreType = "BKS" SSLEnabled = "true" clientAuth = "false" protocol = "HTTP / 1.1" схема = "Https" secure = "true" sslProtocol = "TLS" sslImplementationName = "org.bouncycastle.jce.provider.BouncyCastleProvider" />
    • Перезагрузите сервер после этих изменений.

  • Настройка BouncyCastle для Android-клиента
    • Не нужно настраивать, так как Android поддерживает Bouncy Castle Version 1.46 внутренне в предоставленном «android.jar».
    • Просто выполните свою версию HTTP-клиента (MyHttpClient.java можно найти ниже) и установите в коде следующее:
      • SSLSocketFactory.setHostnameVerifier (SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    • Если вы этого не сделаете, это дает исключение, как показано ниже.
      • Javax.net.ssl.SSLException: имя хоста в сертификате не соответствует: <192.168.104.66>! =
    • В режиме производства измените приведенный выше код на
      • SSLSocketFactory.setHostnameVerifier (SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);

MyHttpClient.java

 package com.arisglobal.aglite.network; import java.io.InputStream; import java.security.KeyStore; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.SingleClientConnManager; import com.arisglobal.aglite.activity.R; import android.content.Context; public class MyHttpClient extends DefaultHttpClient { final Context context; public MyHttpClient(Context context) { this.context = context; } @Override protected ClientConnectionManager createClientConnectionManager() { SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); // Register for port 443 our SSLSocketFactory with our keystore to the ConnectionManager registry.register(new Scheme("https", newSslSocketFactory(), 443)); return new SingleClientConnManager(getParams(), registry); } private SSLSocketFactory newSslSocketFactory() { try { // Get an instance of the Bouncy Castle KeyStore format KeyStore trusted = KeyStore.getInstance("BKS"); // Get the raw resource, which contains the keystore with your trusted certificates (root and any intermediate certs) InputStream in = context.getResources().openRawResource(R.raw.aglite); try { // Initialize the keystore with the provided trusted certificates. // Also provide the password of the keystore trusted.load(in, "aglite".toCharArray()); } finally { in.close(); } // Pass the keystore to the SSLSocketFactory. The factory is responsible for the verification of the server certificate. SSLSocketFactory sf = new SSLSocketFactory(trusted); // Hostname verification from certificate // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506 sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); return sf; } catch (Exception e) { throw new AssertionError(e); } } } 

Как вызвать вышеуказанный код в классе Activity:

 DefaultHttpClient client = new MyHttpClient(getApplicationContext()); HttpResponse response = client.execute(...); 

Я использую Portecle , и он работает как шарм.

Я не думаю, что ваша проблема связана с хранилищем BouncyCastle; Я думаю, проблема связана со сломанным пакетом javax.net.ssl ​​в Android. Хранилище BouncyCastle является высшим раздражением, потому что Android изменил поведение Java по умолчанию, не документируя его нигде, и удалил поставщика по умолчанию, но он работает.

Обратите внимание, что для аутентификации SSL вам может потребоваться 2 хранилища ключей. Хранилище «TrustManager», которое содержит сертификаты CA и хранилище ключей KeyManager, которое содержит ваши общедоступные / закрытые ключи на клиентском сайте. (Документация несколько расплывчата в том, что должно быть в хранилище ключей KeyManager.) Теоретически вам не нужно иметь хранилище ключей TrustManager, если все ваши сертификаты подписаны «хорошо известными» полномочиями Certifcate, например Verisign, Thawte, и так далее. Дайте мне знать, как это работает для вас. Для вашего сервера также потребуется CA для всего, что было использовано для подписи вашего клиента.

Я не мог создать SSL-соединение, используя javax.net.ssl. Я отключил проверку подлинности SSL клиента на стороне сервера, и я все еще не смог создать соединение. Поскольку моей конечной целью был HTTPS GET, я попытался использовать HTTP-клиент Apache, который поставляется вместе с Android. Это сорт. Я мог бы сделать соединение HTTPS, но я все еще не мог использовать SSL auth. Если я включил SSL-аутентификацию клиента на моем сервере, соединение завершится с ошибкой. Я не проверял код HTTP Apache HTTP, но я подозреваю, что они используют собственную реализацию SSL и не используют javax.net.ssl.

Не уверен, что вы решили эту проблему или нет, но так я это делаю и работает на Android:

  1. Используйте openssl для объединения сертификата клиента (сертификат должен быть подписан CA, принятым сервером) и закрытый ключ в пару ключей формата PCKS12: openssl pkcs12 -export -in clientcert.pem -inkey clientkey.pem -out client.p12
  2. Возможно, вам понадобится патч для JRE для шифрования с неограниченной прочностью, зависит от вашей ключевой силы: скопируйте файлы jar из JCE 5.0 неограниченной силы Jurisdiction Policy FIles и переопределите их в JRE (например. C: \ Program Files \ Java \ jre6 \ lib \ security )
  3. Используйте инструмент Portecle, упомянутый выше, и создайте новое хранилище ключей с форматом BKS
  4. Импортируйте пару ключей PCKS12, сгенерированную на шаге 1, и сохраните ее как хранилище ключей BKS. Это хранилище ключей работает с аутентификацией клиента Android.
  5. Если вам нужна цепочка сертификатов, вы можете использовать этот инструмент IBM: KeyMan для объединения пары ключей PCKS12 клиента с сертификатом CA. Но он генерирует только хранилище ключей JKS, поэтому вам снова понадобится Protecle, чтобы преобразовать его в формат BKS.

командная строка:

 keytool -genseckey -alias aliasName -keystore truststore.bks -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /path/to/jar/bcprov-jdk16-1.46.jar -storetype BKS 

Ваша команда для создания хранилища BKS выглядит правильно для меня.

Как инициализировать хранилище ключей.

Вам нужно смириться и передать свой SSLSocketFactory. Ниже приведен пример использования Apache org.apache.http.conn.ssl.SSLSocketFactory

Но я думаю, что вы можете сделать то же самое на javax.net.ssl.SSLSocketFactory

  private SSLSocketFactory newSslSocketFactory() { try { // Get an instance of the Bouncy Castle KeyStore format KeyStore trusted = KeyStore.getInstance("BKS"); // Get the raw resource, which contains the keystore with // your trusted certificates (root and any intermediate certs) InputStream in = context.getResources().openRawResource(R.raw.mykeystore); try { // Initialize the keystore with the provided trusted certificates // Also provide the password of the keystore trusted.load(in, "testtest".toCharArray()); } finally { in.close(); } // Pass the keystore to the SSLSocketFactory. The factory is responsible // for the verification of the server certificate. SSLSocketFactory sf = new SSLSocketFactory(trusted); // Hostname verification from certificate // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506 sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); return sf; } catch (Exception e) { throw new AssertionError(e); } } 

Пожалуйста, дайте мне знать, если это сработает.

Используйте это руководство http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/ Это руководство действительно помогло мне. Важно соблюдать последовательность сертификатов в магазине. Например: сначала импортируйте самый младший сертификат промежуточного ЦС, а затем весь путь до корневого сертификата ЦС .