2013-07-15 112 views
4

我手裏有一個SSL LDAP服務器證書。我想用它來使用UnboundID SDK連接到LDAP服務器。如何使用UnboundID SDK通過SSL服務器證書連接到LDAP服務器?

我不想用com.unboundid.util.ssl.TrustAllTrustManager因爲在這裏顯示: Using UnboundID SDK with an SSL certificate file to connect to LDAP server in Android app

以下TrustManagers不適合我們的產品要求:

com.unboundid.util.ssl.PromptTrustManager 
com.unboundid.util.ssl.HostNameTrustManager 
com.unboundid.util.ssl.ValidityDateTrustManager 

我不想任何用戶交互,以及我在TrustManager上方列表中錯過的驗證證書頒發者的內容。

而且,我不想插入任何密鑰庫的LDAP服務器證書,所以我不能使用以下 TrustManagers:

com.unboundid.util.ssl.WrapperKeyManager 
com.unboundid.util.ssl.PKCS11KeyManager 
com.unboundid.util.ssl.KeyStoreKeyManager 

我想要做的東西像下面的代碼:

CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
Certificate cert = cf.generateCertificate(byteArrayInputStream); 
SSLUtil sslUtil = new SSLUtil(new CertificateTrustManager(cert)); 
SSLSocketFactory socketFactory = sslUtil.createSSLSocketFactory(); 
LDAPConnection connection = new LDAPConnection(socketFactory, 
    "server.example.com", 636); 

請注意,CertificateTrustManager在UnboundID SDK中不存在。 怎麼可能做到這一點?

回答

4

我發現該解決方案使用Using UnboundID SDK with an SSL certificate file to connect to LDAP server in Android appHow to import a .cer certificate into a java keystore?(Patrick M的答案)。

現在我可以從UI拿證書,並通過SSL :)

import com.unboundid.ldap.sdk.LDAPConnection; 
import com.unboundid.util.ssl.SSLUtil; 
import org.junit.Test; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import javax.net.ssl.SSLSocketFactory; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.TrustManagerFactory; 
import java.io.ByteArrayInputStream; 
import java.security.KeyStore; 
import java.security.cert.Certificate; 
import java.security.cert.CertificateFactory; 

String base64EncodedCertificateString = "..."; 
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64EncodedCertificateString.getBytes()); 
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
trustStore.load(null); 
CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
int i = 0; 
while (byteArrayInputStream.available() > 0) { 
    Certificate cert = cf.generateCertificate(byteArrayInputStream); 
    trustStore.setCertificateEntry("cert " + i++, cert); 
} 

TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); 
tmf.init(trustStore); 
TrustManager[] trustManagers = tmf.getTrustManagers(); 
SSLUtil sslUtil = new SSLUtil(trustManagers); 
SSLSocketFactory socketFactory = sslUtil.createSSLSocketFactory(); 
LDAPConnection connection = new LDAPConnection(socketFactory); 
connection.connect("place.myserver.com", 636); 
3

如果您需要信任某個特定的證書或一組證書,那麼您可以創建自己的自定義javax.net.ssl.X509TrustManager實現來檢查提供的證書鏈並確定它是否表示預期的證書。您可以將有關這些證書的信息硬編碼到您的代碼中(或者更好的是,將其放置在配置文件中,以便在不更改任何代碼的情況下更改它)並執行比較證書指紋等以獲得相應程度的確保實際上是合法的證書。

如果您不知道個人證書是什麼,但知道他們都有一個共同的發行人,並且您相信發行人只頒發了優質證書,那麼您可以爲該發行人包含信託信息。

如果您想允許一系列未知證書,可能來自不受信任的發行者(您不知道這些發行者可能會提前發佈什麼內容),並且您不希望提示用戶是否信任他們(你可能會緩存,所以你只需要問一次),然後我不知道你可以做什麼。除非您可以找到一些方法來區分證書與優質服務器,否則您的應用程序將面臨信任不良證書或不信任好證書的風險。

+0

感謝您的回答(+1)!我找到了解決方案。很高興聽取您的意見。 – Michael

-1

雖然不建議出於安全的原因,有時可能至少進行測試的情況下使用TrustAllTrustManager有用的連接到LDAP如下:

TrustAllTrustManager tm = new TrustAllTrustManager(); 
TrustManager[] trustManagers = new TrustManager[] {tm}; 
SSLUtil sslUtil = new SSLUtil(trustManagers); 
SSLSocketFactory socketFactory = sslUtil.createSSLSocketFactory(); 
LDAPConnection connection = new LDAPConnection(socketFactory); 

這不應該用於生產環境!

相關問題