Jak mogę mieć wiele certyfikatów SSL dla serwera Java
Mam wewnętrzny serwer HTTP napisany w Javie; pełny kod źródłowy do mojej dyspozycji. Serwer HTTP może skonfigurować dowolną liczbę witryn internetowych, z których każda będzie miała oddzielne gniazdo nasłuchiwania utworzone za pomocą:
skt=SSLServerSocketFactory.getDefault().createServerSocket(prt,bcklog,adr);
Korzystając ze standardowego magazynu kluczy utworzonego przy użyciu keytool Java, nie mogę przez całe życie wypracować, w jaki sposób uzyskać różne certyfikaty powiązane z różnymi gniazdami nasłuchiwania, aby każda skonfigurowana witryna internetowa miała swój własny certyfikat.
Jestem teraz w szczypaniu, więc niektóre przykłady kodu, które ilustrują, byłyby najbardziej doceniane. Ale doceniłbym każdy dobry przegląd tego, w jaki sposób JSSE łączy się w tym zakresie (przeszukałem dokumentację JSSE firmy Sun, aż mój mózg boli (dosłownie; chociaż może to być tak dużo wycofania kofeiny)).
Edytować
Czy nie ma prostego sposobu na użycie aliasu do powiązania certyfikatów serwera w magazynie kluczy z gniazdami nasłuchiwania? Po to aby:
Klient ma jeden magazyn kluczy do zarządzania wszystkimi certyfikatami iNie ma potrzeby bawić się w wielu sklepach z kluczami itp.Odnosiłem wrażenie (wcześniej tego popołudnia), że mogę napisać prosty KeyManager, tylko zchooseServerAlias(...)
wracając nie-null, to jest nazwa aliasu, którego chciałem - każdy ma jakieś przemyślenia na ten temat rozumowania?
Rozwiązanie
Rozwiązanie, którego użyłem, zbudowane zslyvarkingodpowiedzią było utworzenie tymczasowego magazynu kluczy i zapełnienie go żądanym kluczem / certyfikatem wyodrębnionym z pojedynczego zewnętrznego magazynu kluczy. Kod jest następujący dla wszystkich zainteresowanych (wartość svrctfals to mój „alias certyfikatu serwera”):
SSLServerSocketFactory ssf; // server socket factory
SSLServerSocket skt; // server socket
// LOAD EXTERNAL KEY STORE
KeyStore mstkst;
try {
String kstfil=GlobalSettings.getString("javax.net.ssl.keyStore" ,System.getProperty("javax.net.ssl.keyStore" ,""));
String ksttyp=GlobalSettings.getString("javax.net.ssl.keyStoreType" ,System.getProperty("javax.net.ssl.keyStoreType" ,"jks"));
char[] kstpwd=GlobalSettings.getString("javax.net.ssl.keyStorePassword",System.getProperty("javax.net.ssl.keyStorePassword","")).toCharArray();
mstkst=KeyStore.getInstance(ksttyp);
mstkst.load(new FileInputStream(kstfil),kstpwd);
}
catch(java.security.GeneralSecurityException thr) {
throw new IOException("Cannot load keystore ("+thr+")");
}
// CREATE EPHEMERAL KEYSTORE FOR THIS SOCKET USING DESIRED CERTIFICATE
try {
SSLContext ctx=SSLContext.getInstance("TLS");
KeyManagerFactory kmf=KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore sktkst;
char[] blkpwd=new char[0];
sktkst=KeyStore.getInstance("jks");
sktkst.load(null,blkpwd);
sktkst.setKeyEntry(svrctfals,mstkst.getKey(svrctfals,blkpwd),blkpwd,mstkst.getCertificateChain(svrctfals));
kmf.init(sktkst,blkpwd);
ctx.init(kmf.getKeyManagers(),null,null);
ssf=ctx.getServerSocketFactory();
}
catch(java.security.GeneralSecurityException thr) {
throw new IOException("Cannot create secure socket ("+thr+")");
}
// CREATE AND INITIALIZE SERVER SOCKET
skt=(SSLServerSocket)ssf.createServerSocket(prt,bcklog,adr);
...
return skt;