我有一個用Java編寫的內部HTTP服務器;完整的源代碼在我的處置。 HTTP服務器可以配置任意數量的網站,其中的每一個將與創建一個單獨的監聽套接字:如何爲Java服務器獲得多個SSL證書
skt=SSLServerSocketFactory.getDefault().createServerSocket(prt,bcklog,adr);
使用與Java密鑰工具創建標準密鑰存儲,我不能爲我的生活工作如何獲取與不同偵聽套接字關聯的不同證書,以便每個配置的網站都擁有自己的證書。
我現在在這個時候捏,所以一些代碼示例說明將非常感激。但是,儘可能多地感謝JSSE在這方面如何掛在一起的良好概述(我搜索了Sun的JSSE doco,直到我的大腦受傷(從字面上看,儘管它可能與咖啡因一樣多)。
編輯
是否有使用別名的服務器證書與偵聽套接字密鑰存儲相關聯沒有簡單的方法?因此:
- 客戶有一個密鑰存儲管理所有證書和
- 沒有必要反覆折騰多個密鑰存儲等
我得到的印象(今天下午早些時候)我可以寫一個簡單的KeyManager,只有chooseServerAlias(...)
返回非null,這是我想要的別名的名稱 - 任何人都有任何想法推理?
解
我使用的解決方案,從slyvarking的回答是內置創建臨時密鑰存儲,並使用從單數外部密鑰存儲提取的期望的鍵/證書填充它。代碼如下任何誰是興趣(svrctfals是我的「服務器證書別名」值):
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;
你可以很容易地實現自己的KeyManager,但是你的建築在內存中使用別名新的臨時密鑰庫進入「主」鑰匙店的想法是好的。 – erickson 2009-11-24 06:43:12