Ich habe einen internen HTTP-Server in Java geschrieben; vollständiger Quellcode zu meiner Verfügung. Der HTTP-Server kann eine beliebige Anzahl von Web-Sites konfigurieren, müssen von denen jede eine separate Buchse mit erstellt hören:Wie kann ich mehrere SSL-Zertifikate für einen Java-Server haben
skt=SSLServerSocketFactory.getDefault().createServerSocket(prt,bcklog,adr);
ein Standardschlüsselspeicher mit dem keytool Java erstellt verwenden, kann ich nicht für das Leben von mir heraus wie man verschiedene Zertifikate erhält, die mit verschiedenen Listen Sockets verbunden sind, so dass jede konfigurierte Website ihr eigenes Zertifikat hat.
Ich bin in einer Zeit Pinch für diese jetzt, so einige Codebeispiele, die veranschaulichen würde am meisten geschätzt werden. Aber so viel würde ich jeden guten Überblick darüber schätzen, wie JSSE in dieser Hinsicht zusammenhängt (ich habe Sun JSSE doco gesucht, bis mein Gehirn weh tut (wörtlich; obwohl es genauso viel Koffeinentzug sein könnte)).
bearbeiten
Gibt es keine einfache Möglichkeit, die Aliasnamen zu verwenden, um die Server-Zertifikate in einem Schlüsselspeicher mit den hören Steckdosen zu verbinden? So dass:
- Der Kunde einen Schlüsselspeicher hat für alle Zertifikate zu verwalten, und
- Es gibt keine Notwendigkeit, mehrere Schlüssel speichert ist herumzudaddeln mit etc.
Ich war immer den Eindruck, (früher heute Nachmittag), dass ich einen einfachen KeyManager schreiben könnte, mit nur chooseServerAlias(...)
Rückgabe nicht-null, das ist der Name des Alias, den ich wollte - hat irgendjemand irgendwelche Gedanken zu dieser Argumentationslinie?
Lösung
Die Lösung, die ich verwenden, von slyvarking ‚s Antwort gebaut war ein temporären Schlüsselspeicher und füllen Sie es mit dem gewünschten Schlüssel/cert aus den Einzahl externen Schlüsselspeichern extrahierte zu erstellen. Code folgt für alle, die interessiert sind (svrctfals ist mein „Serverzertifikat alias“ Wert):
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;
Sie können Ihren eigenen KeyManager ziemlich einfach implementieren, aber Ihre Idee, einen neuen, temporären KeyStore im Speicher unter Verwendung eines Alias im "Master" -Schlüsselspeicher zu erstellen, ist ein guter. – erickson