Я использую 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);
Кроме того, я сделал некоторые исследования и от того, что я понял до сих пор: Клиент имеет действительную цепочку сертификатов, но не отправьте его, потому что сервер сообщает, что он принимает только эмитентов, перечисленных сервером.
Если это правильно, то как я могу преодолеть эту проблему?
Я думал о отдельном самозаверяющем ЦС, который доставляется всем клиентам, и который также указан в списке одобренных сервером эмитентов. Любой клиент использует этот ЦС для подписания собственного сертификата. Я не вижу проблемы безопасности с этим. Или есть лучшее решение?
Здесь что-то не так. Использование аутентификации клиента и принятие любого сертификата клиента противоречат друг другу. Зачем использовать аутентификацию клиента, если вам все равно, кто такие клиенты, или имеют ли они действительные сертификаты? NB вам не нужен OpenSSL: Java упакован с использованием криптографических API. – EJP
Я использую сертификат клиента как токен входа. Неизвестные сертификаты будут загружаться как новые клиенты и зарегистрированы. Поэтому есть причина для обоих. И, к сожалению, у Java нет полного пакета криптова. Мне даже нужно использовать Bouncycstle только для создания самоподписанных сертификатов на стороне клиента.Я использовал openssl только из-за его параметра s_client, который позволяет вам проверить, работает ли ваше SSL-соединение. – Chris