/ / Uwierzytelnianie dowolnego certyfikatu klienta w protokole SSL - java, android, ssl, ssl-certificate, sslengine

Uwierzytelnianie dowolnego certyfikatu klienta w protokole SSL - java, android, ssl, ssl-certificate, sslengine

Używam Netty na Androida i po stronie serweraustanowić połączenie SSL z uwierzytelnianiem klienta. Teraz mam problemy z łączeniem się z tymi certyfikatami, ponieważ SSLEngine odmawia ich z powodu "zerowy łańcuch certyfikatów".

Właśnie to zrobiłem po stronie serwera. Skonfigurowałem SSLContext z podpisaną certyfikacją serwera (klient zna ten urząd certyfikacji, aby mógł sprawdzić poprawność tego).

Aby serwer akceptował jakiekolwiek certyfikaty od klientów (ponieważ wszystkie są samopodpisane), zaimplementowałem DummyTrustManager, który po prostu zaakceptuje dowolny.

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];
}
}

Chodzi o to, że nie jestem całkiem pewien metody getAcceptedIssuers ().

  • Jeśli odwołam się do pustej tablicy od pliku opensl-binary (którego używam do ustawienia bardzo poprawnego), to zawiedzie z powodu pustej listy AcceptedIssuers.

  • Jeśli dodam łańcuch certyfikatów serwerów prądu, to będzie on działał przynajmniej dla certyfikatów klienta, które zostały podpisane przez to samo, ale nie dla tych, które są podpisane (to jest to, czego potrzebuję).

Ale może robię coś złego po stronie klienta:

        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);

Zrobiłem też kilka badań iz tego co wiemrozumiane do tej pory: klient ma prawidłowy łańcuch certyfikatów, ale nie wysyła go, ponieważ serwer mówi, że akceptuje tylko wystawców wymienionych przez serwer.

Jeśli tak, to jak mogę rozwiązać ten problem?

Myślałem o oddzielnym, samopodpisanym CAjest dostarczany do wszystkich klientów i jest również wymieniony na liście akceptowanych serwerów. Każdy klient używa tego urzędu certyfikacji do podpisania własnego certyfikatu. Nie widzę problemu związanego z bezpieczeństwem. Czy istnieje lepsze rozwiązanie?

Odpowiedzi:

1 dla odpowiedzi № 1

Ponieważ nie było odpowiedzi na dłuższy okres, przedstawię krótki przegląd tego, jak rozwiążę to na teraz.

Utworzyłem inny urząd certyfikacji, który nie jest podpisany przez żadenzaufany CA. W rzeczywistości jest to samo podpisane. Ten CA jest przeznaczony dla wszystkich klientów do podpisywania własnych certyfikatów. Czemu? W ten sposób mogę nakazać serwerowi wysłanie tego CA jako jedynego zaakceptowanego getAcceptedIssuers (). Nie ma to na celu nadania poziomu autorytetu. Sposób, w jaki sprawdzam klientów jest tylko ich kluczem publicznym, więc nie ma tam ryzyka bezpieczeństwa.

Musisz tylko zachować ostrożność, aby nie mieszać swoich instancji TrustedManagers i SSLContext.