【发布时间】:2013-08-19 21:24:12
【问题描述】:
我正在编写一个可以从远程服务器获取 Ldap 证书的项目。当服务器不需要相互认证时,它适用于一般模式。但是当我尝试需要相互认证的服务器时,它会失败。代码如下:
String serverSpec = null;
boolean enableAnonSuites = false;
boolean isTracing = false;
// Try and parse command line arguments.
try {
serverSpec = "ldap://10.47.16.60:389";
}
catch (Exception e) {
trace(true,e.toString());
usage();
return;
}
try {
// Create a SocketFactory that will be given to LDAP for
// building SSL sockets
MySocketFactory msf = new MySocketFactory(isTracing,
enableAnonSuites);
// Set up environment for creating initial context
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
// Must use the name of the server that is found in its certificate
env.put(Context.PROVIDER_URL,
serverSpec
);
// Create initial context
trace(isTracing,"Creating new Ldapcontext");
LdapContext ctx = new InitialLdapContext(env, null);
// Start
trace(isTracing,"Performing StartTlsRequest");
StartTlsResponse tls = null;
try {
tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
}
catch (NamingException e) {
trace(true,"Unable to establish SSL connection:\n"
+e);
return;
}
// The default JSSE implementation will compare the hostname of
// the server with the hostname in the server's certificate, and
// will not proceed unless they match. To override this behaviour,
// you have to provide your own HostNameVerifier object. The
// example below simply bypasses the check
tls.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session)
{
return true;
}
});
// Negotiate SSL on the connection using our own SocketFactory
trace(isTracing,"Negotiating SSL");
SSLSession sess = null;
sess = tls.negotiate(msf);
X509Certificate[] cert = sess.getPeerCertificateChain();
异常信息如下:“javax.net.ssl.SSLException: Received fatal alert: internal error”,发生在“negotiate”方法。我分析了wireshark的trace信息,确定这是因为服务器需要相互认证。现在,我想知道 com.sun.jndi.ldap 包中是否有某些类可能对这个问题有用。有人可以帮忙吗?
【问题讨论】:
标签: java ldap certificate jndi starttls