Badamy platformę powiadomień push dla Androida (awaryjne przełączanie dla C2DM Google) Używam klienta Java Eclipse Paho do łączenia się z brokerem mosquitto (1.0.3). Broker jest zainstalowany na systemie Ubuntu 12.04 (instancja AWS EC2) Udało mi się połączyć klienta z serwerem przy użyciu niezaszyfrowanego połączenia TCP. Nawiasem mówiąc, po poprawieniu parametrów jądra, udało mi się otworzyć 100K klientów współbieżnych do jednej instancji brokera na średniej wielkości maszynie EC2. Dobra robota, mosquitto!Połączenie SSL od klienta Java (Eclipse Paho) do brokto mosquitto: "unknown_ca"
Teraz próbuję skonfigurować bezpieczne połączenie przy użyciu protokołu SSL. Chcę uwierzytelnić klienta przy użyciu certyfikatu klienta. Poszedłem za objaśnieniami w mosquito_tls page i wygenerowałem klucze i samopodpisane certyfikaty dla serwera i klienta. Skonfigurowano serwer tak, aby korzystał z protokołu SSL.
Dla części klienta przyjrzałem się podpisowi mosquitto_tls_set i zauważyłem, że wymaga on certyfikatu CA, klucza klienta i plików certyfikatu. Uznałem, że certyfikat CA jest używany do uwierzytelniania serwera przez klienta, a klucz klienta i certyfikat są używane do uwierzytelniania klienta przez serwer. Mam rację?
Więc tutaj jest to, co zrobiłem po stronie Java:
- Zastosowanie nadmuchiwany zamek do załadowania trzech wymienionych plików.
- Umieść certyfikat CA w magazynie kluczy i użyj go do utworzenia TrustManagerFactory.
- Umieść klucz klienta i certyfikat w innym magazynie kluczy, a następnie użyj go do utworzenia obiektu KeyManagerFactory o numerze .
- Utworzono SSLContekst i zainicjalizowano go dwiema fabrykami.
- Utworzono SSLSocketFactory z SSLContext i przekazał ją do MqttConnectOptions w PAHO za
Kiedy ja connect, pojawia się następujący komunikat o błędzie z mosquitto
OpenSSL Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
Socket read error on client (null), disconnecting.
Edit: teraz widzę na po stronie klienta następujący wyjątek
javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
Oto pełny kod
static SSLSocketFactory getSocketFactory (final String caCrtFile, final String crtFile, final String keyFile, final String password) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
X509Certificate caCert = (X509Certificate)reader.readObject();
reader.close();
reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
X509Certificate cert = (X509Certificate)reader.readObject();
reader.close();
reader = new PEMReader(
new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
new PasswordFinder() {
public char[] getPassword() {
return password.toCharArray();
}
}
);
KeyPair key = (KeyPair)reader.readObject();
reader.close();
KeyStore caKs = KeyStore.getInstance("JKS");
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(caKs);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
ks.setCertificateEntry("certificate", cert);
ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
//ks.setKeyEntry("public-key", key.getPublic(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password.toCharArray());
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
mosquito.conf wygląda to
# general options
pid_file /home/ubuntu/mosquitto.pid
# persistence
queue_qos0_messages false
persistence false
# logging
log_dest stdout
connection_messages true
log_timestamp false
# default listener
# disable default listener (open only SSL listener)
#port 1883
#max_connections -1
# SSL listener
listener 1883
cafile /home/ubuntu/etc/ca.crt
certfile /home/ubuntu/etc/server.crt
keyfile /home/ubuntu/etc/server.key
require_certificate true
use_identity_as_username true
max_connections -1
I stworzył istotę git z przykładowy kod powyżej, jak również pełnego wyjaśnienia wszystkich niezbędnych kroków, aby uczynić tę pracę: https: //gist.github. com/4104301 –
"szczegóły podane podczas generowania certyfikatu ...muszą być różne w certyfikatach urzędu certyfikacji, klienta i serwera " Czy zdajesz sobie również sprawę, dlaczego jest to wymagane? – mvmn