你可以這樣使用X509TrustManager實現。
獲得一個與SSLContext中
SSLContext ctx = SSLContext.getInstance("TLS");
然後用SSLContext#init與您的自定義X509TrustManager
初始化。 SecureRandom和KeyManager []可能爲空。後者只有在執行客戶端身份驗證時纔有用,如果在您的方案中只有服務器需要進行身份驗證,則無需設置它。
從此SSLContext,使用SSLContext#getSocketFactory讓您的SSLSocketFactory和按計劃進行。
由於涉及您的X509TrustManager實現,它看起來是這樣的:
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
//do nothing, you're the client
}
public X509Certificate[] getAcceptedIssuers() {
//also only relevant for servers
}
public void checkServerTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
/* chain[chain.length -1] is the candidate for the
* root certificate.
* Look it up to see whether it's in your list.
* If not, ask the user for permission to add it.
* If not granted, reject.
* Validate the chain using CertPathValidator and
* your list of trusted roots.
*/
}
};
編輯:
瑞安是正確的,我忘了說明如何將新的根添加到現有的。假設您當前的受信任根的KeyStore源自cacerts
(位於jre/lib/security下的JDK附帶的'Java默認信任庫')。我假設你用KeyStore#load(InputStream,char [])加載了這個密鑰存儲(它是JKS格式)。
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream in = new FileInputStream("<path to cacerts"");
ks.load(in, "changeit".toCharArray);
如果您還沒有更改它,則默認密碼cacerts
是「changeit」。
然後你可以使用KeyStore#setEntry添加addtional信任的根。您可以省略ProtectionParameter(即null),KeyStore.Entry將是一個TrustedCertificateEntry,它將新的根作爲參數傳遞給其構造函數。
KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(newRoot);
ks.setEntry("someAlias", newEntry, null);
如果你想堅持的改變信任存儲在某些時候,你可能會KeyStore#store(OutputStream, char[]實現這一目標。
這可能有點晚,但http://jcalcote.wordpress.com/2010/06/22/managing-a-dynamic-java-trust-store/此鏈接有幫助。 – goh