2013-05-14 3 views
0

Я использую Netty на Android и на стороне сервера, чтобы установить SSL-защищенное соединение с аутентификацией клиента. Теперь мне трудно связаться с этими сертификатами, поскольку SSLEngine отклоняет их из-за «null cert chain».Удостоверение любого сертификата клиента в SSL-Handshake

Это то, что я сделал на стороне сервера. Я установил SSLContext с подписанным сертификатом сервера (клиент знает CA, чтобы он мог проверить его).

Чтобы сервер принимал какие-либо сертификаты от клиентов (поскольку они все самозаверяются), я применил DummyTrustManager, который будет просто принимать любые.

private static class DummyTrustManager implements X509TrustManager 
    { 
     private X509Certificate[] mCerts; 

     public DummyTrustManager(Certificate[] pCerts) 
     { 
      // convert into x509 array 
      mCerts = new X509Certificate[pCerts.length]; 
      for(int i = 0; i < pCerts.length; i++) 
      { 
       mCerts[i] = (X509Certificate)pCerts[i]; 
      } 
     } 

     @Override 
     public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{} 

     @Override 
     public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{} 

     @Override 
     public X509Certificate[] getAcceptedIssuers() 
     { 
      return mCerts; 
      //return new X509Certificate[0]; 
     } 
    } 

Дело в том, что я не совсем уверен в методе getAcceptedIssuers().

  • Если я retrurn пустого массива, чем OpenSSL-бинарный (который я использую для veryfi правильной установки) не удается из пустого списка AcceptedIssuers.

  • Если я добавлю цепочку сертификатов сервера токов, то он будет работать, по крайней мере, для клиентских сертификатов, которые были подписаны одним и тем же чаем, но не с теми, которые были подписаны самостоятельно (что мне и нужно).

Но, может быть, я делаю что-то неправильно на стороне клиента:

 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keyStore.load(null); 

     keyStore.setEntry("user_certificate", new KeyStore.PrivateKeyEntry(mPrivate, new Certificate[]{mClientCert}), this); 
     keyStore.setCertificateEntry("server_certificate", mServerCert); 

Кроме того, я сделал некоторые исследования и от того, что я понял до сих пор: Клиент имеет действительную цепочку сертификатов, но не отправьте его, потому что сервер сообщает, что он принимает только эмитентов, перечисленных сервером.

Если это правильно, то как я могу преодолеть эту проблему?

Я думал о отдельном самозаверяющем ЦС, который доставляется всем клиентам, и который также указан в списке одобренных сервером эмитентов. Любой клиент использует этот ЦС для подписания собственного сертификата. Я не вижу проблемы безопасности с этим. Или есть лучшее решение?

+0

Здесь что-то не так. Использование аутентификации клиента и принятие любого сертификата клиента противоречат друг другу. Зачем использовать аутентификацию клиента, если вам все равно, кто такие клиенты, или имеют ли они действительные сертификаты? NB вам не нужен OpenSSL: Java упакован с использованием криптографических API. – EJP

+1

Я использую сертификат клиента как токен входа. Неизвестные сертификаты будут загружаться как новые клиенты и зарегистрированы. Поэтому есть причина для обоих. И, к сожалению, у Java нет полного пакета криптова. Мне даже нужно использовать Bouncycstle только для создания самоподписанных сертификатов на стороне клиента.Я использовал openssl только из-за его параметра s_client, который позволяет вам проверить, работает ли ваше SSL-соединение. – Chris

ответ

1

Поскольку ответа на более длительный период я ​​не приведу, я дам краткий обзор того, как я сейчас это разрешу.

Я создал другой ЦС, который не подписан никаким доверенным ЦС. На самом деле он подписан сам. Этот ЦС предоставляется всем клиентам для подписания собственных сертификатов. Зачем? Потому что таким образом я могу сказать серверу отправить этот CA как единственный принятый номер getAcceptedIssuers(). Это не предназначено для предоставления полномочий. То, как я проверяю клиентов, - это только их открытый ключ, поэтому риска для безопасности там нет.

Вам нужно быть очень осторожным, чтобы не смешивать экземпляры TrustedManagers и SSLContext.

+0

Риск безопасности заключается в том, что ЦА будет утечка от одного из ваших клиентов кому-то, кто не заплатил, или что бы вы ни пытались защитить. Вы действительно очень мало сделали здесь. – EJP

+1

Как упоминалось ранее. Я не использую SSL так, как это делают большинство людей. Мне нужно установить соединение, в котором клиент использует открытый ключ вместо имени пользователя/пароля. Я мог даже за исключением каждого эмитента, так как я проверяю любого клиента своим открытым ключом и ** не ** эмитентом. Публичный ЦС - это всего лишь способ обмануть (что я хотел бы пропустить, если смогу, о чем я и говорил) Java, потому что в противном случае клиентская сторона вообще не отправляет какой-либо сертификат. Любой открытый ключ, который я не знаю, является новым и может регистрироваться на моем сервере. – Chris

 Смежные вопросы

  • Нет связанных вопросов^_^